Sectool|从AWVS插件到伪代理扫描2 — SQL盲注插件

0x00 前言

在上一篇文章中,我们提到了AWVS的几个插件,并对其中的 classXSS, classSQLI等几个插件进行了分析, 接下来的重头戏是对AWVS的盲注插件的分析, 即在 ./PerScheme/Blind_Sql_Injection.script这一插件的分析。

0x01 插件的结构

在这个插件中, 可以看到由类 classBlindSQLInj和以下几个函数构成:

在上一篇中提到,像 alert这种函数,其实是在获取到漏洞信息之后反馈给AWVS的系统用于记录的,所以可以不关注。同时根据对 sqli-labs进行测试后发现,其实AWVS对于 benchmark注入的算法并不算太精确, 这点在后面会提到 ,所以重点放在了 testInjection, testInjectionWithOR, testInjectionWithOR2 等函数中。 接下来还是以入口进行分析,在该插件中,入口是一个for循环,

所以,重点还是在于classBlindSQLInj这个类中,下面我们开始对这个类进行分析

0x02 重点函数分析

在上一小节所列出的classBlindSQLInj这个类中函数,我们可以将其分为以下几类:

  1. 测试函数,包括testInjection,testOOB,testTiming
  2. 确认函数,包括confirmInjection,confirmInjectionWithOR等
  3. 功能函数,包括filterBody,extractTextFromBody,checkIfResponseIsStable等函数

下面我们进行功能函数的分析,再进行测试函数的分析,最后是确认函数的分析

功能函数

extractTextFromBody函数

怎么说呢, 其实开发都应该向AWVS一样,将函数名写的十分的易懂。 这个函数如其名称,是从html文本中提出text, 而减少了关于不同访问的标签属性的变化而带来的影响(猜的)。 具体看一下:

代码其实很简单了,将body中的标签取出,一旦遇到/STYLE和/SCRIPT的标签,其includeText为TRUE,虽然htmlToken这个函数没有具体的代码,但是应该不难猜测类似于js中的dom树。python中bs4这个库中也相关的函数如:.next_sibling等。一言以敝之, 这个函数是去标签化的过程。

filterBody函数

在了解了上一个函数之后, filterBody也就很好分析了

首先判断 Content-Type的响应是否包含了 html字段,其次过滤掉了时间相关的字段值,最后处理原始值与测试值是否需要在响应中去除,最后返回结果。

checkIfResponseIsStable函数

对于时延注入来说, 检测响应是否稳定应该是相对比较重要的功能了。 AWVS的实现方式如下:

  • 对原始参数值分别请求两次, 获取其body1= filterBody(), body2= filterBody() 和响应的时间time1, time2
  • 如果在请求原始参数过程中报错了,直接return。如果请求未出错,则计算在两次原始参数值请求中所消耗的最短时长 shortDuration, 与最长时间 longDuration, 这两个变量首先在类创建的时候是有一个初始值的,如 longDuration=6, shortDuration=2, 在进行这两次原始值的请求后,对变量的更新操作如下:

  • 在AWVS中的responseStable中,分别对responseTimingIsStable,responseIsStable与inputIsStable做了检测,在得到上面shortDuration和longDuration之后,下边是如何就几种Stable的类型做判断的

  • 如果到这一步还没有return,那么继续进行下一步,生成一个随机数来检测响应是否稳定,即生成一个随机数var3,用它当参数来请求获取body3=filterBody()与time3并用time3与min_time和max_time做比较来得出新的min_time和max_time.之后重新进行三种Stable状态的判断

确认函数

在功能函数讲完之后, 下一步我们先进行确认函数的分析,最后才是测试函数. 先看一下awvs的 confirmInjection函数的定义

confirmInjection函数

<span class=""> </span>

其中

  • varIndex 表示在本次测试的参数在所有参数中所占的位置
  • quoteChar 表示特殊的字符 如 ', "等
  • likeInjection 表示是否是like注入,
  • confirmed 表示是否已经确认过了

然后声明了几个变量

接着在测试的主体中,将参数值分成了数字与字符两种,对于数字的型的测试流程如下,awvs的测试 payload很多,主要是True/False两种,下面只对每一种举例:

将一些调试信息过滤后,其主要的测试步骤如上:对于True的Payload生成条件为: (origValueAsInt).toString()+"*1*1", 如原始值为2, 那么payload为:2*1*1, 然后如果请求没有出错,那么将响应值对于filterBody函数所过滤过出的testBody与origBody相对比,如果两个值不相等,即判定为不存在注入漏洞。

因为如果存在注入漏洞时,2*1*1 的响应应该等于 2。相对应的,测试False的Payload值:(origValueAsInt+10).toString()+"*5*2*999" 对其响应做处理后判断与origBody相等,则判定不存在漏洞,直接return

没错,对于数字的注入只用了这两种方法,惊喜不惊喜,意外不意外,开心不开心?其所有的payload如下:

其函数主体是对这六个Payload的乱序请求, 一旦其中一个payload返回的False, 直接返回False。

接下来是测试字符串的payload, 同样还是对于true/false的payload举例两个:

同样的,payload的生成规则与数字一样, 就不再重复叙述了, 这里把awvs中的payload列下

除了数字与字符型的payload,awvs还提供了一种common型,即不管数字或者字符都可以直接用的..检测过程一样,直接上payload:

当然当然,awvs并不只是有and的注入,还包括or的注入,同时因为or的注入也是通过检测testBody是否与origBody相符来判断的,所以老规矩,举例两个然后直接上payload

confirmInjectionWithOR与confirmInjectionWithOR2函数

其测试TRUE与FALSE的条件如下:

与上一个小节的confirmInjection一样,通过不同的or条件下testBody与origBody是否一致来判断漏洞的存在与否,其payload如下:

其函数主体是对上述的payload进行乱序请求,如果某一条未返回False, 则直接返回 False,否则返回True

测试函数

BO!BO!BO! 下面看一下awvs的时延注入检测函数,这一部分需要跨度两个函数,即:testTiming与startTest,其实startTest相当于入口函数了。

testTiming函数

在分析这个函数的时候,首先我们需要进入startTest函数看一下payload相关代码, 同样,因为包含了mysql,mssql等,这里只分析一下mysql的, mssql的相关代码同样是使用了 testTiming的函数, 可以payload来自己分析

上边将两条Payload传入了testTiming函数

这里看到有{SLEEP}标志符,后边会用它来替换成将要休眠的秒数 在函数中首先有四个函数分别是:

这四个函数分别对应休眠秒数为 long, zero, mid, verylong这四个级别的长度的检测方法,而这四个长度是由上文提到的 longDuration与 shortDuration这两个变量相互组合而来的,是简单的加减法,在函数 genSleepString中,不再多叙述。

接下来分别用 lzvm分别代表 long, zero, verylong, mid这四个级别,生成了一个由 lzvm字符排列的序列, 并附加了一个固定的字符串 zzzlz:

对于这里的每一个字符,调用对应的函数来检测, 这里举 verylong来举例

可以看出实现很简单,替换 {SLEEP}等替代符之后,发送请求判断响应时间与预定时间的大小来对漏洞是否存在返回TRUE/FALSE, 后边还对这四个函数的返回值如time1,time2,time3,time4做了一个简单的比较,举例来说,time1代表 verylong级别,time2代表 mid级别, 那么如果 time1<time2, 表示注入不存在。 其他函数与此相同,不再多叙述。 除此之外,关于mysql的还有 benchmark这种关于时延注入的payload, 但是在awvs中, benchmark不同次数之后与一个固定的秒数相比较, 可能会因为网络的原因而出现误报, 所以本次不进行分析,不过大致的流程与上边的sleep是一样的, 可以自己看一下代码

startTesting函数

看到这里,应该对整个脚本的流程有了一个清楚的认识,我们先看整个函数的代码是怎么样的:

首先是为没有值的参数设置了默认的数字 1作为其值,然后初始化一些变量,接着根据变量的值来判断是否进行mysql, mssql,postsql等数据库的测试,并通过不同的字符如 ', "等来调用前边分析的函数进行时延,布尔等注入类型的测试, 代码相对比较简单,结合前边的几个主要函数,可以对盲注更深入的了解了。

0x03 总结

本篇文章主要对awvs的盲注进行了简单的分析,通过分析它的函数代码,可以学习到一款成熟的扫描器是如何就SQL注入这个漏洞进行的分析与利用,同时对于自己扫描器中的也可以增加一款新插件。 另外不知道有没有注入到一点,在盲注这一个脚本中,并没有发现宽字符注入这一个注入点的检测,所以还可以就这几个函数,新增加一个检测宽字符注入的payload, 百尺竿头,更进一步。 另外还有order by的注入也在里边,有兴趣的可以看一下,流程与上边的类似。

0x04 参考

  • 对AWVS的一次简单分析
    • https://paper.seebug.org/461/
  • mysql-blind sql injection with awvs
    • https://security.stackexchange.com/questions/137251/blind-sql-injection-with-acunetrix-vulnerability-scanner#160103
  • awvs blindsqlinjection.script
    • https://github.com/fnmsd/awvs_script_decode/blob/master/Scripts/PerScheme/Blind_Sql_Injection.script
  • 从AWVS插件到伪代理扫描

本文由 孤独常伴 作者:孤独常伴 发表,其版权均为 孤独常伴 所有,文章内容系作者个人观点,不代表 孤独常伴 对观点赞同或支持。如需转载,请注明文章来源。

0

发表评论