一个月黑风不高的夜晚,测试还在进行。因为客户环境比较敏感,测试通常选择在业务低峰期进行。眼看着快到收工时间,回家的地铁可不能错过。

就在这时,扫描工具发出了提示,发现了一个有趣的异常。

问题出现在一个名为 sort 的参数上,其原始值为 desc。测试时,在其后分别附加了 ,111 和 ,1,服务器返回了截然不同的响应。
简单来说,这类似于联合查询注入中常用的 order by 技巧,用于判断数据表的列数。当我们尝试按第“111”列排序时,数据库自然找不到这个不存在的列,于是直接抛出了详细的错误信息。这通常意味着,sort 参数的值被直接拼接到了 SQL 语句的 ORDER BY 子句中。
漏洞原理与利用
对于这类排序注入漏洞,在大多数没有防护的情况下,利用起来并不需要什么高深的技巧。如果存在 WAF 等防护设备,才需要考虑绕过的“手法”。如果没有任何检测,事情就变得非常简单了。
核心思路就是直接尝试在参数值后拼接 SQL 语句,观察是否能够被执行。我们首先尝试一个时间盲注的 Payload。

可以看到,请求中我们尝试拼接了 (sleep(1))。虽然不知道为什么设定的1秒延迟实际等待了更长时间,但服务器确实执行了这段代码并产生了延迟,这说明我们的SQL注入是成功的。
既然能执行任意代码,并且错误信息会回显,那么报错注入就是最直接的选择。我们从错误信息中已经知道后端使用的是 MySQL 数据库。

上图展示了一个典型的报错注入 Payload。通过构造特定的 XPATH 语法错误,我们可以让数据库在执行排序操作时,将查询结果(如数据库名、版本信息等)通过错误信息带出来。从响应中可以看到,updatexml 函数被成功执行并触发了 XPATH 语法错误,这为后续提取数据铺平了道路。
总结
这次遇到的排序参数注入非常典型:缺乏有效的输入过滤,错误信息完全暴露,使得漏洞的发现和利用都异常顺畅。整个安全测试过程没有复杂的绕过,纯粹是对 SQL 语法特性的利用。这也提醒开发者在编写代码时,必须对用户传入的、用于排序、分页等操作的参数进行严格的校验或参数化处理,绝不能直接拼接。
对于更复杂的、存在过滤的排序注入场景,则需要根据具体的过滤规则进行技巧性绕过。关于排序注入的更多高级技巧与实战案例,欢迎在云栈社区的技术论坛中与大家继续深入探讨。
|