SQL注入漏洞的攻击注入类型和常规的漏洞利用思路

sqlmap中的注入类型说明

使用sqlmap-hh可以查看到具体的操作说明

在这里插入图片描述

Techniques
这些选项可用于调整特定SQL注入技术的测试。

--technique=TECH.. 用于选择要使用的SQL注入技术(默认为"BEUSTQ")。
--time-sec=TIMESEC 用于设置延迟数据库管理系统(DBMS)响应的时间(默认为5秒)。
--union-cols=UCOLS 用于指定要测试的联合查询SQL注入的列范围。
--union-char=UCHAR 用于指定用于列数枚举的字符。
--union-from=UFROM 用于指定联合查询SQL注入中FROM部分要使用的表。
--dns-domain=DNS.. 用于域名用于DNS渗透攻击。
--second-url=SEC.. 用于搜索第二次响应的结果页面的URL。
--second-req=SEC.. 用于从文件中加载第二次HTTP请求。

这些选项能够让用户配置SQL注入测试的各种参数和注入类型,以便更准确的测试SQL注入漏洞。


使用sqlmap进行sql注入测试

下面sqlmap自动测试的类型有在图中标注说明:
在这里插入图片描述


通过请求类型区分

  1. GET注入
    注入的payload直接放在请求的url里,通常是有长度限制的,中文需要URL编码;

  2. POST注入
    payload是放在body里面,没有长度限制;

  3. COOKIE注入
    放在请求头信息里面,提交payload的时候服务端会从请求头信息读取;

  4. Referrer注入
    也是放在请求头信息里面,在payload里添加SQL语句向服务端发送请求,再通过返回判断是否存在注入点;

  5. XFF注入
    在请求头信息里面,全称为X-Forwarded-For简称XFF头,也是直接将payload放在请求头信息里,服务端会从客户端提交的信息来读取。
    通常可以使用下面的payload进行尝试:

X-Forwarded-for: 127.0.0.1' and 1=1#

通过注入参数数据类型区分

int整型

SELECT * FROM sys_users WHERE id = 1

string字符串型

SELECT * FROM sys_users WHERE name = "admin"

like搜索型(模糊匹配)

SELECT * FROM sys_users WHERE email LIKE "%@qq.com%"

SQL常规的漏洞利用思路

  1. 第一步肯定是寻找注入点,可使用批量测试扫描工具进行,如上面的sqlmap
  2. 获取到注入点之后,开始尝试进一步获得数据库用户名、数据库名称、当前数据库用户权限、服务器操作系统信息、数据库版本等信息;
  3. 猜解关键数据库表和它的重要字段跟内容,如存放管理员账号的表名、字段名等信息,再进一步获取到数据库管理员账号密码;
  4. 获取到用户信息,寻找后台登陆测试,再进一步利用。

手工注入思路

  1. 也是和常规思路差不多,第一步首先判断是否存在注入点,存在注入点的话继续确认是字符型还是数字型的注入参数;
  2. 猜解查询语句中的字段数,使用order by N
  3. 确定显示的字段顺序;
  4. 获取当前数据库;
  5. 获取数据库中的表;
  6. 继续获取表中的字段名;
  7. 查询到账户的数据。

这里根据上面的sqlmap使用说明的类型来逐个介绍sql注入的类型

关于dvwa靶场的php源码中的sql注入漏洞,可以先了解一下php中调用mysql的函数,以下是参考链接: php连接和操作mysql数据库超全详解!!!

布尔型盲注

dvwa对应的布尔型盲注的前端页面是这样的:
在这里插入图片描述

布尔型盲注漏洞的dvwa参考代码如下,当然这是low级别的:


<?php

if( isset( $_GET[ 'Submit' ] ) ) {
    // 获取Submit提交输入框的内容
    $id = $_GET[ 'id' ];//结合下图抓取的数据包,这里的id是用户的输入

    // 与数据库交互,把上面的id获取到再拼接到sql语句中来
    $getid  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
    $result = mysqli_query($GLOBALS["___mysqli_ston"],  $getid ); // mysqli_query通常使用这个函数来执行sql语句

    // 获取结果条数使用mysqli_num_rows函数
    $num = @mysqli_num_rows( $result ); // The '@' character suppresses errors
    if( $num > 0 ) {
        // 如果返回的条数大于零,则打印结果信息
        echo '<pre>User ID exists in the database.</pre>';
    }
    else {
        // 否则表示失败
        header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );

        // 返回这个消息给用户
        echo '<pre>User ID is MISSING from the database.</pre>';
    }

	//这下面的代码则是php连接数据库的常规流程,关闭数据库连接的操作
    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>


结合抓包工具分析这个页面里头的细节操作
在这里插入图片描述
通过上面的分析可以指导id这个变量的值是用户输入的,如果在数据库里存在则打印存在的信息给用户,否则打印不存在的信息给用户。这种只返回指定信息的,不显示任何数据库内容的场景,如果这里存在sql注入,则称为盲注,其中又细分成布尔型盲注和延时注入(盲注的一种)。

测试盲注

一种,使用1' and '1'='11' and '1'='2判断两者返回的页面是否一样,来检测此处是否存在注入点;

第二种,使用sleep函数来测试是否存在注入点
在这里插入图片描述

盲注经验技巧

在测试或者已经发现存在sql盲注点的时候,可以结合php的另外几个函数进一步渗透测试,如下:

  • if(1,2,3)函数,如函数声明,它有三个参数,第一个是表达式、第二个是若表达式为真则显示,第三个参数是表达式不成立则显示;
    - substring(1,2,3)函数,第一个参数是字符串、第二个是开始截取的位置、第三个参数是截取该字符串的长度;
  • database()函数,直接使用

上面的三个函数既可以单独使用,也能结合一起使用。

报错型注入

web程序在执行数据库语句遇到语法不对的场景时,会给客户回显报错的信息,比如

1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1

数据库报错信息存在的意义是为了让开发人员在调试程序的时候可以快速定位问题。
php执行sql语句的时候一般会采用异常处理函数来捕获错误信息。

例如:

  • mysqli_error()函数
  • mysqli_connect_error()函数

调用方式如下图,下面贴一下dvwa中关于sql注入的源码:
在这里插入图片描述

报错注入攻击方法

比较常见的是在web测试点输入一个“ ‘ ”单引号字符来测试站点是否存在报错注入。

下面举一个简单的例子,查看当前数据库名:

SELECT first_name, last_name FROM users WHERE user_id = '1' and info()--
//这里会报错,如下图,说当前库不存在info这个函数,以这种方式可以推断出当前数据库名

在这里插入图片描述

报错注入攻击深入

通过下面的链接,我是本地测试环境,来进一步对报错注入漏洞站点进行深入

http://www.dvwa.com/vulnerabilities/sqli/?id=1%27%20and%20(updatexml(1,concat(0x7e,(select%20user()),0x7e),1))--+&Submit=Submit#

在这里插入图片描述

使用updatexml()函数,通过函数名可以猜到,它的作用是update修改xml数据,它有三个参数,分别是文件对象名称、文件路径以及修改的值。函数声明如下:

updatexml(XML_document,XPath_string,new_value)

如上面的测试图所示,当路径出现语法错误的时候mysql就会报错,这里的0x7e表示" ~ "字符,在xpath语法中是错误的,所以导致报错。
除了上面的updatexml()函数之外,还有以下函数可以在sql报错注入的时候利用:

  • floor()
  • extractvalue()
  • geometrycollection()
  • multipoint()
  • polygon()
  • multipolygon()
  • linestring()
  • multilinestring()
  • exp()

报错型注入攻击的一般流程

  1. 获取到报错注入点,通过该注入点得到库名;
  2. 接下来获取mysql的账号密码;
  3. 通过mysql的内置库进一步获取表名;
  4. 基于上面的步骤继续获取字段名;
  5. 然后再继续获取值,也就是内容信息;

堆叠注入

堆叠注入攻击是利用了mysql堆叠查询可查询多条sql语句的特点来构造payload对注入点进行攻击。

mysql中通常是通过mysqli_multi_query()以及mysql_multi_query()这两个函数来执行一个或多个针对数据库的查询。

堆叠注入的危害是很大的,可以任意使用增删改查的语句,例如删除数据库、修改数据库、添加数据库等高危操作。

时间注入攻击

时间注入属于盲注的一种。在mysql中可以利用sleep()函数来进行时间注入。它的参数值是整型,sleep(20)就表示数据库延时20秒再返回内容。在注入点测试的时候可以使用

' and sleep(20)

来观察网页响应时间,由此来判断是否存在sql注入。
一般实际渗透场景中,通过一条简单的if判断语句来判断是否存在时间注入

select if(2>1,sleep(10),0) 2>1
#通常都是这么使用,用来判断数据库名的长度或者关键字段的长度等等

UNION 联合注入攻击

SQL联合查询的操作符是UNION,它既可以单张表联合查询,也支持多表联合查询,在SQL注入里面通常的应用场景是多表联合查询,多表联合查询的关键字是UNION SELECT,操作符上下两个结果集的列数必须相等,否则会报错。

举一个例子(是在搭载了dvwa靶场的phpadmin里面操作的),查询guestbook表和users表的字段信息,其中guestbook表有三个字段,而users的字段数是八个,如果直接SELECT *,它会因为字段数不等导致报错,如下:

SELECT * FROM `guestbook` WHERE comment_id = 1 UNION SELECT * FROM `users`;

在这里插入图片描述

正确的写法是:

SELECT * FROM `guestbook` WHERE comment_id = 1 UNION SELECT 1,2,3 FROM `users`;

在这里插入图片描述

在SQL注入攻击的应用场景下,上面的这些1,2,3字段换成具体的字段名称或者换成SQL自带的函数,可以获取到想要的数据,如下:

SELECT * FROM `guestbook` WHERE comment_id = 1 UNION SELECT database(),user(),version() FROM `users`;

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值