之前,有其他安全工作者自己开发proxy+sqlmapapi的方式批量检测( http://www.freebuf.com/tools/74445.html ),小哥我最近偶尔也在看sqlmap源代码(为什么说偶尔?做为一只甲方安全汪,杂事太多T_T),这次给大家带来的方式是通过sqlmap提取history记录实现批量sql检测。
讲到这里,可能你会吐嘈“sqlmap里不是有个-r或-l参数提取burp的history记录批量检测么?搞毛毛啊!”……先听我讲sqlmap源代码有个小bug,导致不能全量检测会漏掉一些URL和参数。
具体源代码如下: lib/core/option.py 中 _parseBurpLog() 模块代码第366行,如下图:
当kb.targets不为空或url不在addedTargetUrls里时就添加检测队列,这会导致什么问题呢?
例如:
#1:
post /1.php a=ok&b=ok
#2:
post /1.php a=ok&c=inject
两个url相同#1的参数不存在注入,#2的c参数存在注入。但sqlmap在批量提取url时由于两个url相同,所以只取了#1,而#2因为url跟#1的url一样,所以没添加到检测队列里。就这样我们的sqlmap就漏测#2存在注入的c参数了(真实被坑过)。
基于以上原因,我决定对sqlmap加入检测队列算法进行修造, 加入检测队列在url的基础上加入data的key做为判断条件(url+key),这样相同url而key不同请求history记录sqlmap也不漏测 。
首先,把data里的Key提取出来,并对key进行一次按字符顺序排序,然后跟url组合是否加入检测队列的判断条件。
具体实现代码如下:
if not(conf.scope and not re.search(conf.scope, url, re.I)): #处理data参数,把key提取出来,key值做为判断重复的条件之一 a = data b = a.split('&') #print b c = [] for i in b: if i.find('=') > 0: arr = i.split('=') c.append(arr[0]) #print c #提取的key使用sorted按字符顺序排序一把,再组合成字符串。(如果数据庞大的话,建议把keystr转成hash值) keystr = "%s%s"%(url,''.join(sorted(c))) #if not kb.targets or url not in addedTargetUrls: if not kb.targets or keystr not in addedTargetUrls: kb.targets.add((url, method, data, cookie, tuple(headers))) #addedTargetUrls.add(url) addedTargetUrls.add(keystr)
测试数据:
优化前:
优化后:
sqlmap真的很强大,大家可以熟读sqlmap源代码做二次开发,加入新功能比如检测XXE,LIF,RCE等功能,让sqlmap功能变得更强大。好了,本篇文章到此结束,很感谢大家很有耐心的看完本篇文章。如果有什么好玩的点子,想法也希望大家一起交流、学习、进步,谢谢。