- A+
撸撸看sqlmap 盲注返回判断
1 背景
研究这个主要碰到了两个疑问:
1):自己的插件在安全测试某些盲注点的时候,经常出现误报
2):如果在返回的页面里面出现了url请求中提交的内容,由于每次提交的内容不一样,这样会导致返回的内容也不一样,这种情况下是如何判断是否存在注入的呢?
2 场景
搭建了个场景,大概情况如下,我每次都会输出执行的sql语句,aid参数存在sql注入漏洞,这样当我输入 and 123=123 和and 321=123的时候,除了a b显示情况的差异,输出的sql语句是否也会影响我们的注入结果呢.
3 分析
好久没有看相关代码了,流程有点不熟悉了,于是重调试了一下代码。
大致逻辑:
1):sqlmap.py main()函数下调用了start()
2):controller.py start()函数调用了checkSqlInjection()
3):checks.py checkSqlInjection()函数里发生了盲注相关的逻辑判断。
关键部分代码在checkSqlInjection函数中如下:
大致意思就是首先去获得了一个trueResult 和 一个 falseResult。trueResult的请求代表的就是 and 1=1,而falseResult的请求代表的就是 and 1=2。接着我们就详细的看一下这个trueResult和falseResult的逻辑与处理。
我们下断点跟踪到trueResult处:
此时打印出来的reqPayload为and 1798=1798 和我们预期的一样,我们跟进下,进入到Request.queryPage函数,位于connect.py文件下。
利用Connect.getPage将内容发送出去了。返回的结果存储到了page,headers,code中
接着下面的逻辑就会处理page页面了,我们通过调试可以看到第一个关键函数,removeReflectiveValues,
感觉将page和payload联系到了一起,它俩应该有关系。通过该函数的处理后我们去输出结果:
画横线部分本来应该是and 1=1类似的内容,但是sqlmap认为该内容属于reflect内容,在处理page之前,想将该部分内容做了替换。
接着跟进代码,进入到最后的comparsion,应该是对于该内容进行相关比较,与谁比较呢?
比较部分的代码位于comparison.py下,函数为_comparsion。
将template的值赋给了seq1,猜测的话应该是和原始的请求进行比较。将and 1=1 和原始的页面比较。
在该函数的处理的时候,又碰到一个关键处理函数removeDynamicContent,通过查看上下文,大致意思去除动态的内容,动态的内容是根据页面生成的。
处理动态内容之后,就是比较seq1和seq2了,核心部分如下,比较seq1和seq2的时候,将字符串REFLECTED_VALUE_MARKER替换为空,这个时候我们的内容如下:
其实在这里就已经知道了我们之前的两个疑问的答案了,我们接着分析完整个流程,这里返回结果为True,接着就会进入到:
如果falseResult为False,流程和之前的差不多,则存在注入。
4 补充
看到上面之后,可能会有个疑问,就是有了这样的page的值之后道,sqlmap到底是如何进行比较的。我们接着看下sqlmap到底是如何处理的。
上面得到了seq1和seq2后,存入到了seqMatcher。然后需要计算一个ratio的值:
ratio = round(seqMatcher.quick_ratio(), 3),一个比例值。
我们跟踪quick_ratio(),得到如下的代码,位于difflab.py文件下:
这里计算的思路是统计了seq1和seq2中各个字符出现的次数,然后将seq1和seq2进行了match记录了匹配的次数,然后结果进入到了calculate_ratio中进行计算:
可以看到计算的值就是2倍匹配的次数除以二者长度之和。
我们的逻辑进入到了最后的一个else的判断中,true的时候返回了true,false的时候返回了false,于是证明存在注入。
5 结果
先看我这种场景下的注入显示的结果。
以上说明sqlmap是能够自动识别我的这种情况的,并且添加了处理。这种场景经常出现在例如一些报错注入的情况下,还有一些服务器打印调试信息的情况下。