SELECT * FROM (
SELECT TMP_PAGE.*,ROWNUM ROW_ID FROM (
SELECT * FROM (
SELECT a.id as "id",a.xxx as "xxx",……(反正有很多列) FROM
FROM wl a
LEFT JOIN t_user u
ON u.id=a.sszh WHERE jgzt="1" and (
YXQX="-1" or time > ADD_MONTHS(sysdate,0-YXQX*12)
)
ORDER BY 0
))
TMP_PAGE)
WHERE ROW_ID <= ? AND ROW_ID >?
该sortField参数会传到ORDER BY语句到后面,即ORDER BY {sortField}
最近看到一个大佬的渗透报告,里面有一个排序注入的利用。太久没有手工注入SQL了,一时间看得有点懵,花了点时间研究了一下,并记录成这篇博客。由于设计到真实生产系统,截图就不多给了,直接口头表述。如果有不清楚的,还请见谅。
存在SQL注入的接口存在一个sortField参数,传入值为0,会报错,响应包回显SQL查询语句
该sortField参数会传到ORDER BY语句到后面,即ORDER BY {sortField}
此时记录一下ORDER BY 0 的响应包,稍后进行进一步注入的时候会用到
因为看不到这个查询语句在干啥?我把它丢进了GPT分析,分析结果如下:
这个查询语句是一个复杂的Oracle SQL语句,主要用于从数据库中检索特定条件下的分页数据。让我详细解释一下:
wl
表中选择了一系列列。LEFT JOIN
将该表与t_user
表关联,连接条件是u.id = a.sszh
。jgzt="1"
,表示选取状态为"1"的记录。(YXQX="-1" or time > ADD_MONTHS(sysdate, 0 - YXQX * 12))
,这是一个日期比较,根据条件选取符合要求的记录。ORDER BY 17
表示按照第17列排序。ROWNUM
给每一行结果分配一个行号,并将这个行号作为ROW_ID
的别名。SELECT
语句,筛选出ROW_ID
在指定范围内的记录,实现分页效果。关于order by 注入,更多的可能关注这篇文章 ORDER BY 注入 这里就不多讲原理了。
因为是渗透测试报告,我没有机会手动进行测试,只能通过口头了解知道该系统对逗号进行了过滤。
针对该过滤,大佬使用了参数污染,基本原理如下:
针对该原理使用payload 为:
首先先解释一下各类函数的作用:
其中
expression
是需要比较的值,search1
,search2
, ... 是要匹配的条件,result1
,result2
, ... 是匹配到相应条件时返回的结果,default_result
是当没有条件匹配时返回的默认结果。而
&
则是使用同参数名来给函数传参,最后服务器处理的结果会是:(返回包里也有)语句的结果就是:
取
user
的第一个字母,若跟chr(103)匹配,则产生一个除零报错,若不匹配,则跟ORDER BY 0产生同样的错误(这就是为什么我让大家把前面ORDER BY 0的错误记下来)总结:大佬的思路就是牛!我SQL注入就是SQLMAP一把梭,有就有,没有就没有了哈哈哈。