内容简介:一次使用sqlmap过程中,它无法检测出一个很明显的布尔型回显注入,很好奇sqlmap如何检测不出。再加上有写检测注入工具的想法,看看sqlmap究竟是如何自动判断boolean型注入。这里是存在boolean型注入,sqlmap检测不出来了。
0x00 前言
一次使用sqlmap过程中,它无法检测出一个很明显的布尔型回显注入,很好奇sqlmap如何检测不出。再加上有写检测注入 工具 的想法,看看sqlmap究竟是如何自动判断boolean型注入。
0x01 无法检测boolean注入
这里是存在boolean型注入,sqlmap检测不出来了。
但是当把”33333333”增长一点,sqlmap是提取到”33333333…”作为了关键词来判断哪个页面正确哪个页面错误。
那sqlmap是如何提取的呢?
0x02 分析
sqlmap之所以能成为神器,因为它考虑了很多,代码也就很多,但是我对其他的技术细comparison节不太感兴趣,所以只针对如何检测boolean进行详细追溯。开始分析的时候,看代码的时候是根据关键词往上溯,这里是从上往下看。
通过上图,通过sqlmap显示的info,找到关键词 with --string=
,来到 sqlmap-masterlibcontrollerchecks.py
,再寻找if、while之类的看下代码的流程,来到 478行
从注释可以看到,这里是boolean型检测开始,下面还有其他的error-based、time-based、UNION query。明白自己所在的位置,大概分析的范围。
genCmpPayload
这个函数用于生成boolean类型payload,
kb.matchRatio
是原始页面和 id=原始值
+ "),'.)(((,
报错页面的相似度。
kb.negativeLogic
是负逻辑,用一个负的随机数然后添加or的payload,where其他值可以在 sqlmap-masterxmlpayloadsboolean_blind.xml
看到具体含义。
接下来是 queryPage
函数,这个函数比较重要,它有一个修饰器,在 sqlmap-masterlibcoredecorators.py
中,threadData比较重要,它存储着上次请求的请求的各种数据,用来进行对比数据。在这个修饰的作用是为了当函数调用失败的时候,如果函数增加了往threadData.valueStack增加了数据,可以进行删除,从而恢复原来未调用函数之前的状态。下面是threadData存储的内容。
queryPage
还会根据参数值,返回不同的结果,比较关键的是 getRatioValue
参数,因为这个参数的bool值影响里面最为关键函数comparison返回值。
comparison
函数,也是根据getRatioValue参数,返回不同的结果,当getRatioValue为True的时候,返回与原始页面的相似度。
为False的时候,返回Bool值:
ratio > UPPER_RATIO_BOUND(0.98),返回True。 ratio < LOWER_RATIO_BOUND(0.02)为False。 (ratio - kb.matchRatio) > DIFF_TOLERANCE(0.05),允许%0.05的误差。
很多情况下payload会回显在页面上,sqlmap这里是把payload替换成 REFLECTED_VALUE ,然后对比的时候再把这些干扰因素去掉。
再通过threadData给falsePage, truePage返回包的各种参数(用于后面提取特征)。并通过 queryPage
获取相似度。进入到下一步判断。
这里有一个 kb.nullConnection
,通过checkNullConnection函数进行检测,
1、HEAD方法请求,判断返回包里面是否有Content-Length。(近iis6支持)
2、增加Header头Range: bytes=-1,通过len判断返回报body的长度是不是等于1。(这个测试了apache、nginx、Apache-Coyote/1.1都无效)
3、直接通过判断返回报文里面是否有Content-Length,如果有则说明支持skip-read。(仅仅读取Content-Length的长度,来作为判断注入的依据)
当取Content-Length作为判断的时候的相似度计算公式,这里注意一点,这里有一个取倒数
ratio = 1. * len(seqMatcher.a) / len(page) if ratio > 1: ratio = 1. / ratio
因为多字节的问题,”路飞”,len(“路飞”)为2,而Content-Length为4。这样会导致ratio大于1。
再看下下面的判断
前面是发送正确的payload返回true,现在拿false的payload发送,测试是否返回false。如果错误页面的相似度也高于0.98则进入提取特征的环节,并不会判定为为注入。如果错误页面低于0.98虽然也会进入获取页面特征环节,但是此时已经被标注成了注入了。
在标记注入前,如果 kb.heavilyDynamic
(太多的变量了),还会进行一次使用ture payload判断是否如何规则。然后才把injectable置为true。
函数 getFilteredPageContent
通过正则 <script.+?</script>|<!--.+?-->|<style.+?</style>|<[^>]+>|t|n|r
去掉所有的标签和script和css样式代码,通过对比正确的页面和错误页面收集的关键词,减去差集获取特征候选者。
获取到特征候选者还会继续判断是不是仅仅由字符,逗号,句号,感叹,空格构成,里面是否又感叹号,是长度大于10,这样才之后才能成为特征值。
这里主要是用于在判断了可能存在注入,提取一些特征,比如返回状态码、返回字符串。函数 extractTextTagContent
通过正则 <(abbr|acronym|b|blockquote|br|center|cite|code|dt|em|font|h\d|i|li|p|pre|q|strong|sub|sup|td|th|title|tt|u)(?!\w).*?>([^<]+)
提取特定标签的text,然后获取正确页面text-错误页面text集合-错误页面的text,得到特征字符串。
提取不返回的字符串,如果没有字符串和状态码这样明显特征,在判定可能存在注入的情况下,就只能靠相似度来识别。
后面判定存在了,做了一些赋值,为后面的注入数据做准备工作。下面还有两个检测过滤工作。
checkSuhosinPatch(injection)
,检查了Suhosin path,因为Suhosin Get类型的,只获取value值前512字节,所以发送超过 512 字节的payload,看是否还存在注入,如果存在,就没有Suhosin path,
payload为:
id=1' and 9703= (512空格) 9703 AND 'DyXn'='DyXn
checkFilteredChars(injection)
,检测大于号和圆括号是否过滤,如果利用下面payload请求返回包的相似度判断是否被过滤。
AND 2210>2209 AND 'mTvV'='mTvV AND (2209)=2209 AND 'ZWWn'='ZWWn
总结
首先会收集原始页面body内容,用于相似度的比较,然后通过相似度初步判断是不是注入,如果判定为注入还会进行提取特征去作为特征值,如果没有只能使用相似度作为判断。
if re.match(r"A[w.,! ]+Z", candidate) and ' ' in candidate and candidate.strip() and len(candidate) > CANDIDATE_SENTENCE_MIN_LENGTH: conf.string = candidate injectable = True
最开始说的那个注入之所以没有检测出,就是因为错误页面的相似度高于0.98,虽然提取出特征出来,但是后面判断特征不符合,放弃了该特征,导致判定没有注入。
而这个判断是不太符合国情的,因为我们语言中使用空格的频率并不高,而英语是一个单词一个空格。
参考
以上所述就是小编给大家介绍的《Sqlmap如何检测Boolean型注入》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Python实现SQL注入检测插件
- 基于卷积神经网络的SQL注入检测
- Angular 4 依赖注入教程之二 组件中注入服务
- 服务端注入之Flask框架中服务端模板注入问题
- 服务器端电子表格注入 - 从公式注入到远程代码执行
- SQL注入测试技巧TIP:再从Mysql注入绕过过滤说起
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Programming Rust
Jim Blandy / O'Reilly Media / 2016-8-25 / GBP 47.99
This practical book introduces systems programmers to Rust, the new and cutting-edge language that’s still in the experimental/lab stage. You’ll learn how Rust offers the rare and valuable combination......一起来看看 《Programming Rust》 这本书的介绍吧!