记一次真实渗透排序处发现的SQL注入学习
字数 1074 2025-08-12 11:33:58
Order By SQL注入漏洞分析与利用
0x00 漏洞背景
在Java Web应用中,特别是使用MyBatis框架时,排序功能(order by)常存在SQL注入风险。这是由于参数化查询的特性与order by语法的特殊要求导致的冲突。
0x01 漏洞原理
参数化查询的限制
- 参数化查询会自动为参数值添加引号
- 但order by字段不能带引号(如
order by 'column'是无效语法) - 开发者不得不直接拼接SQL语句(使用
${}而非#{})
MyBatis框架中的表现
- 安全写法应使用
#{}进行参数化 - 但order by场景下,开发者常改用
${}直接拼接 - 导致用户输入可直接影响SQL语句结构
0x02 漏洞特征
触发条件
- 仅当order参数值为
asc或desc时触发 - 其他值可能不会进入易受攻击的代码路径
注入点识别
- 测试排序接口的column参数
- 观察
undefined等异常参数值的行为 - 注意500错误与200响应的区别
0x03 漏洞验证
初步测试
- 设置order参数为
asc或desc - 在column参数中添加单引号
' - 观察是否产生SQL错误(500响应)
确认注入
使用条件判断payload:
IF(substr(database(),1,1)='a',1,(select 1 union select 2))
解释:
- 如果条件为真,返回1(正常排序)
- 如果条件为假,执行非法UNION操作导致报错
- 通过响应状态码(200/500)判断条件真假
0x04 自动化利用
使用Burp Suite Intruder
- 攻击类型选择"Cluster bomb"
- 设置两个payload:
- Payload 1:位置数字(1-8)
- Payload 2:字母(a-z)
- 配置响应过滤(区分200和500)
爆破过程
对于数据库名:
- 先确定长度:
IF(length(database())=7,1,(select 1 union select 2)) - 逐位爆破字符:
IF(substr(database(),1,1)='i',1,(select 1 union select 2))
0x05 防御措施
安全编码实践
- 使用白名单验证排序字段
- 避免直接拼接用户输入到order by子句
- 在MyBatis中使用安全的XML配置
代码示例
// 不安全
@Select("SELECT * FROM users ORDER BY ${sortField} ${sortOrder}")
// 较安全方式
private static final Set<String> VALID_COLUMNS = Set.of("id", "name", "date");
private static final Set<String> VALID_ORDERS = Set.of("ASC", "DESC");
public List<User> getUsers(String sortField, String sortOrder) {
if (!VALID_COLUMNS.contains(sortField) || !VALID_ORDERS.contains(sortOrder)) {
throw new IllegalArgumentException("Invalid sort parameters");
}
return userMapper.selectUsers(sortField, sortOrder);
}
0x06 总结
Order By注入是Web应用中常见的漏洞类型,特别是在Java/MyBatis环境中。渗透测试时应特别关注:
- 所有排序功能接口
- 参数值为asc/desc时的行为
- 通过条件错误进行盲注的技术
掌握这类漏洞的发现和利用技术,对提升Web安全测试能力至关重要。