sqlmap Bool型&延时型 检测策略分析

0x00 预备-queryPage()

首先先讲一个核心的函数:queryPage()。这个函数在以下分析中贯穿始终。其被用于请求页面, 同时具有多种返回值以适配多种检测策略,见下图:

下面分析一下这几个return的情况。

第一个return:1237行,如果传入timeBasedCompare=True,则return wasLastResponseDelayed(),这个语句会在延时型注入中用到。函数wasLastResponseDelayed()的返回值为一个布尔值,如果上次请求有延迟则为True,反之为False。这个函数的具体的实现见延时型检测策略的判断依据部分。

第二个return:1249行,其中content和reponse都是函数参数传过来的,默认为False,如果为true则返回这次请求的响应体、响应头、响应码。

第三个return:1252行,getRatioValue也为函数参数传来的,如果为True,则返回一个元组,两个元素分别为两个comparison函数的返回值,此元组为(布尔值, ratio)(注:ratio为两次请求的响应内容的重合率,被用作判断页面是否变化的依据)。comparison函数被应用在Bool型盲注中,其具体实现逻辑见bool型检测策略的判断依据部分。

第四个return:1254行,为上一个return的else条件,直接返回ratio值。

0x01 bool型检测策略

首先bool型检测之前,程序会提前检测页面是否稳定(checkStability()),即测试两个参数相同的请求的响应是否相同,如果不同则说明页面中有可能存在类似于时间戳的东西。如果动态内容对页面改动较大(ratio<0.98,ratio为调用quick_ratio的值,此函数原理下方说明),则调用findDynamicContent函数,去定位页面中动态内容的位置,并将其定位存在kb中。

然后到了bool型检测代码段,先上图

首先看到475行调用了queryPage函数,其payload参数位置传入了getCmpPayload(),getCmpPayload这个函数主要是根据每个payload对应的comparison标签构造CmpPayload(用于与payload标签进行比较,比如payload为1=1,那么CmpPaload就是类似为1=2)。可以看到这一步程序没有取queryPage的返回值,因为其主要作用是设置threadData中的lastPage之类的值,用于下一次True请求与之比较。紧接着就会发现476行直接把threadData的几个last变量传给了falsePage\falseHeaders\falseCode,方便下面比较。

接着看到480-482行发送了True逻辑的请求,并将其响应也赋值给对应的truePage\trueHeaders\trueCode。这里queryPage的返回值赋值给了trueResult,这个函数的返回值已经在第0部分中说了,由于这里没有传入什么多余的参数,因此进入的是第四个return,即一个布尔值,代表较ori_page,这个界面是否发生了变化。

然后在484行进行if判断,当true与false响应不同时进入(bool注入可能存在的基础)。进来后再次进行一次false判断用于防止误报,如果comparison返回的还是false,那就基本上确定为存在漏洞。反之,如果这次返回了True,与第一次的结果不同,那么还要进行下一次防止误报,尝试了解为什么会结果不同。

这就来到了505行:

这里的防误报原理主要是提取响应中的文本内容,然后将响应内容中的纯文本内容拿出来进行单独对比(即去掉script、css、注释、html等标签),同理,如果有True响应中有而False中没有的字符串,则确认为有漏洞。

然后剩下的525行之后,如果确认存在漏洞需要进行的内容,就是输出一些bool型注入的判断依据字符之类的东西,这里就不在跟进了。如下图:

判断依据

comparison()函数原理:

经查看代码可以发现,其主要调用的是_comparison(),因此下面对这个函数进行详细的分析。

首先以kb.pageTamplate作为与本次请求对比的响应,这个变量是程序在初始化阶段调用checkConnection()设置的,其请求中不包含payload。

然后在根据上面的动态内容位置,去掉kb.pageTamplate和本次请求响应中的动态内容。见89-90行

最后调用difflib库的quick_ratio方法,计算两者的页面相似比率,将之赋值给ratio。见139行

程序事先定义了两个常量:

LOWER_RATIO_BOUND==0.02
UPPER_RATIO_BOUND==0.98

然后设置kb.matchRatio,当ratio在两者中间时,程序会将ratio赋值给kb.matchRatio。见143-146行

最后return时,此函数分为了以下几种情况:

1.当ratio>0.98时返回True,即判断为页面相同;

2.ratio<0.02时判断为页面不同;

3.return (ratio - kb.matchRatio) > DIFF_TOLERANCE(0.05),kb.matchRatio是一个在0.02与0.98之间的值,在上面已经说了,是在一次请求中使用ratio赋值的。这个return的判断可以转换成ratio>kb.matchRatio+0.05,也就是说ratio必须大于之前的一次ratio至少0.05才行,同时如果ratio>0.98也是直接返回True的(第一次的条件)。

quick_ratio()

统计字符的个数(比如字母a有29个等等),然后拿匹配的字母数*2/两个对比字符串的字符总数

案例

下面看一下在使用正确的boundary突破边界之后,True请求和False请求的最终对比界面是什么。

首先是一个正常请求的响应(www.test.com/index.php?id=2):

第一个框是直接返回url中的参数值,即id=2。

第二个框是时间戳,即保证在每次响应这一部分都是变化的。

第三个框是“you are in”,表示可以在数据库中找到数据,看一下源码:

下面先看一下True请求的响应。

可以看到,第一个框处只有id=,没有id的值,这是因为在进行对比之前,为了避免“payload本身就是不同的”这种影响,实现就已经去掉了这些反射型的参数(类似于xss,即页面直接返回了用户可控的参数)。

再False的响应。

这里也没有第一个框,跟True响应的情况相同。同时这里也没有第三个框,因为这个False语句构建了一个逻辑假的SQL语句,直接导致程序无法在数据库中找到数据。

0x02 延时型

598行开始进行延时型判断,600行调用queryPage函数,返回值为一个布尔值,True表示这次请求产生了延迟(见‘判断依据’部分),code为http响应码。

接着进入603行的if语句,如果上次存在延时则进入(由于payload中使用了[SLEEPTIME],在queryPage中将之替换成了一个值,所以如果存在漏洞则一定会有延时)。

如果进入了这个语句块则再次进行一次时延时间为0的请求,如果还是产生时延则说明为误报。如果没有时延则在611行再进行一次有时延时间的请求,结果如果还是True(与603行结果一致),则确定为存在漏洞。

判断依据

判断本次请求是否产生延迟调用的是wasLastResponseDelayed函数,先放个图:

可以看到,首先计算标准差:deviation。然后在2402行计算lowerStdLimit,值为平均数+7*标准差,以这个值看做一个阈值,作为最大延迟时间(小于0.5时看做0.5)。大于这个数的请求都看做是发生延时的请求。+-7*标准差能保证99.9999999997440%的未延时请求能落在这个区间里。

使用标准差的原因

为什么不是平均值呢,因为标准差更能反映一组数据的离散程度。比如熊的平均体重是140kg,标准差为5kg,那么一只熊的重量可能在135-145kg(根据标准差计算)之间,也有可能在120-160kg(根据平均数猜测)之间。因此仅仅查看所有熊的平均重量就不可能知道单个熊的重量,但是标准差可以告诉你单个熊的可靠重量范围。这就是这里使用标准差的意义。

参考:

1.How Self-Tuning Threshold Baseline is Computed

2.标准差的意义

0xFF参考:

sqlmap 检测剖析 -- 凤雏

Python:SQLMap源码精读—基于时间的盲注(time-based blind) -- 曾是土木人

sqlmap time-based inject 分析 -- 美丽联合SRC

sqlmap基于时间盲注判断原理 -- think_ycx

Sqlmap如何检测Boolean型注入 -- lufei

sqlmap中文手册 -- werner-wiki

超详细SQLMap使用攻略及技巧分享

sqlmap Bool型&延时型 检测策略分析的更多相关文章

  1. 连续型变量的推断性分析——t检验

    连续型变量的推断性分析方法主要有t检验和方差分析两种,这两种方法可以解决一些实际的分析问题,下面我们分别来介绍一下这两种方法 一.t检验(Student's t test) t检验也称student ...

  2. angular 2+ 变化检测系列二(检测策略)

    我们将创建一个简单的MovieApp来显示有关一部电影的信息.这个应用程序将只包含两个组件:显示有关电影的信息的MovieComponent和包含执行某些操作按钮的电影引用的AppComponent. ...

  3. Swift4 基本数据类型(范围型, Stride型, 数组, 字符串, 哈希表)

    创建: 2018/02/28 完成: 2018/03/04 更新: 2018/05/03 给主要标题加上英语, 方便页内搜索 [任务表]TODO 范围型(Range)与Stride型  与范围运算符相 ...

  4. 各种RTMP直播流播放权限_音视频_数据花屏_问题检测与分析工具EasyRTMPClient

    之前的一篇博客<网络摄像机IPCamera RTSP直播播放网络/权限/音视频数据/花屏问题检测与分析助手EasyRTSPClient>,我们介绍了RTSP流的检测和分析工具EasyRTS ...

  5. 安全检测及分析神器—AppScan使用教程

    最近项目准备验收,所以最近在做项目验收的准备工作:我们公司规定,项目的安全检测必须通过才能进行项目验收:公司的安全部门用的检测软件就是大名鼎鼎的IBM Rational Appscan;在教由安全部门 ...

  6. JVM 分代GC策略分析

    JVM 分代GC策略分析   我们以Sun HotSpot VM来进行分析,首先应该知道,如果我们没有指定任何GC策略的时候,JVM默认使用的GC策略.Java虚拟机是按照分代的方式来回收垃圾空间,我 ...

  7. PHP程序污点型漏洞静态检测方法

    这篇文献,作者针对基于PHP语言开发的web应用程序产生的污点型漏洞,提出了一种静态代码分析检测的方法.       先解释一下什么叫污点型漏洞,由于对于用户的输入没有进行有效的过滤,使其进入敏感函数 ...

  8. yolo回归型的物体检测

    本弱又搬了另外一个博客的讲解: 缩进YOLO全称You Only Look Once: Unified, Real-Time Object Detection,是在CVPR2016提出的一种目标检测算 ...

  9. ptrace注入型病毒“聊天剽窃手”分析

    概述 “聊天剽窃手”Windseeker是一款间谍软件,它使用了ptrace进程注入技术,能够对微信和QQ的聊天记录进行监控. 软件安装后的桌面图标和启动界面如图所示:   行为分析 该应用首先获取手 ...

随机推荐

  1. 获取radio、select、checkbox标签选中的值

    <input type="radio" id="radio1" name="radio"><label for=" ...

  2. 成功实现在VS2017下编译含<pthread.h>的代码:

    VS2017配置使用#<pthread.h> https://blog.csdn.net/cry1994/article/details/79115394(原来SystemWow64里面存 ...

  3. jdbc连接阿里云服务器上的MySQL数据库 及 数据库IP限制

    问题1:Jdbc 如何连接阿里云服务器上的MySQL数据库? 解决: 上截图: 其中IP是阿里云服务器的公网IP地址. 问题2:   刚开始接手开发的时候,使用Navicat连接阿里云服务器上的数据后 ...

  4. JavaScript函数节流和函数防抖之间的区别

    一.概念解释  函数节流和函数防抖,两者都是优化高频率执行js代码的一种手段.  大家大概都知道旧款电视机的工作原理,就是一行行得扫描出色彩到屏幕上,然后组成一张张图片.由于肉眼只能分辨出一定频率的变 ...

  5. ArcCore重构-目标文件结构化

    基于官方arc-stable-9c57d86f66be,AUTOSAR版本3.1.5   基本问题 3. 编译系统中所有代码文件通过搜索路径(VPATH)中搜索,存在名称污染问题,需加入路径信息:   ...

  6. cocos2d-x学习之路之工作吐槽

    经过大半年的cocos2d-x的学习,目前已在一个游戏创业公司实习,负责客户端的代码编写和维护.公司做了一款网游.比较给力,马上就要发布了.希望能够大卖.比较坑的是,居然电脑不给联网.查资料都不好查, ...

  7. webpack4.x版本splitChunksPlugin的配置项详解与实际应用场景

    在工程化地使用webpack时,公共代码抽离是不可或缺的,4.x版本之后,commonsChunkPlugin已经被去掉,splitChunksPlugins登上舞台,并且优化了很多配置选项,集体课件 ...

  8. Python并发编程之线程消息通信机制任务协调(四)

    大家好,并发编程 进入第四篇. 本文目录 前言 Event事件 Condition Queue队列 总结 . 前言 前面我已经向大家介绍了,如何使用创建线程,启动线程.相信大家都会有这样一个想法,线程 ...

  9. Lucene入门简介

    一  Lucene产生的背景 数据库中的搜索很容易实现,通常都是使用sql语句进行查询,而且能很快的得到查询结果. 为什么数据库搜索很容易? 因为数据库中的数据存储是有规律的,有行有列而且数据格式.数 ...

  10. PAT1022.:Digital Library

    1022. Digital Library (30) 时间限制 1000 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue A Di ...