作者:鳳雛@安恒掃描器

前言

本文分析的sqlmap是commit編號為591a60bbde434aacc0d90548cd442d6a756ff104的版本,2017年七月份的版本,相對于現在有點老了。不過sqlmap檢測的核心邏輯基本沒變,還是拿著這個源碼做了分析并進行總結。

本文從五個角度去剖析sqlmap的漏洞檢測過程,包括前置發包(一系列探子請求)、布爾盲注、錯誤注入、union注入、時間盲注這五個過程。本文對其中的兩個基礎檢測算法(響應相似度對比技術,高斯分布識別響應機制)進行詳細分析,這也是筆者認為本文的最大亮點。響應相似度對比技術在sqlmap中大量使用,高斯分布識別響應機制在union注入(select null列數探測技術)和時間盲注過程中使用。

本文包含了大量的流程圖,這些流程圖只有筆者認為的關鍵環節才會進行說明,這一點也許對不熟悉SQL注入漏洞自動化的人不友好,不過仔細看看流程圖多思考多Google,我相信你總會懂的。

sqlmap檢測之前置發包

在sqlmap檢測sql注入點的過程中,會有一系列前置發包,這些前置發包主要包括

  1. 網站連通性檢測
  2. WAF探測
  3. 網頁穩定性檢測
  4. 參數動態性檢測
  5. 啟發式注入檢測
  6. 誤報檢測

等發包檢測邏輯。嚴格來說,誤報檢測不屬于前置發包過程,誤報檢測在時間盲注和布爾盲注過程中都有使用,并且具有相同的邏輯特點,檢測流程就在此一并說明,具體發包情況分別在時間盲注和布爾盲注中說明。

在sqlmap中,響應相似度對比技術內置于發包引擎中,可見響應相似度對比技術在sqlmap的重要性,而這些前置發包的一些邏輯也離不開響應相似度對比。行業內通常會有網頁相似度對比的說法,網頁相似度對比在本文中指的是響應相似度對比中HTTP響應體對比分析的結果。因此,在剖析前置發包之前,先看看sqlmap中響應相似度對比技術。

響應相似度對比技術

在sqlmap檢測的整個過程中,會有一個原始響應的定義,指的是在網站連通性檢測的過程中,如果網站成功響應,則把該響應定義為原始響應(包括狀態碼、HTTP響應頭、HTTP響應體)。

sqlmap中,原始響應作為對比過程中被對比的對象,一個請求成功響應后,與原始響應進行對比,得出對比結果,具體的對比流程如下圖所示。

響應體相似度對比圖

這個對比算法的輸入是當前整個響應(包括狀態嗎、HTTP響應頭、HTTP響應體),輸出可以根據需求來選擇(包括網頁相似度比例數值ratio或者布爾值True/False),算法輸出為True表示當前響應與原始響應相似,算法輸出為False表示當前響應與原始響應不相似。兩個響應體的相似度數值(ratio)和相似度布爾值(True/False)的關系如下圖所示。

響應體的相似度數值和相似度布爾值關系圖

其中,ratio是一個介于0-1之間的數值。在sqlmap中,當ratio小于0.02(下邊界)時,相似度布爾值為False;當ratio大于0.98(上邊界)時,相似度布爾值為True;當ratio介于0.02-0.98之間的時候,當ratio > 臨界點(kb.matchRatio,知識庫matchRatio值) + 容差(默認0.05)的時候,相似度布爾值為True,否則,相似度布爾值為False,在這種情況下,關鍵問題就是確定臨界點。

臨界點的確定方法分為兩種情況,分別為:

  1. 布爾盲注過程中一組真假payload對比
  2. 其他

布爾盲注的臨界點確定放到后續的布爾盲注過程中講解,此處講解第二種情況。在第二種情況下,能夠產生臨界點值需要兩個條件同時滿足,分別為:

  1. 該響應需要使用響應相似度對比技術
  2. 首次出現ratio值介于0.02-0.98之間

那么這個ratio值就會作為臨界點值,后續會一直使用。本文后續還會出現“網頁相似度”這個詞語,指的是響應相似度分析技術中的HTTP body對比技術。

響應相似度對比技術作為基礎技術存在與sqlmap中,在整個檢測過程中會大量使用,在介紹前置發包之前,先簡單介紹一下注入環境,結合具體發包來講解,希望能夠好理解一些。

注入場景

假設example.php存在一個注入點,并伴隨一些隨機字符串:

$query = "SELECT * FROM users WHERE id=" . $_GET['id'] . " LIMIT 0, 1";
print "<br>static line<br>";
print str_rand(rand(10,20));

每一次響應都會返回10-20之間任意一個值的隨機字符串,該注入點對應的請求為:

http://target_host/example.php?id=1

假設MySQL數據庫中存在兩條記錄,分別為:

+----+------------------------------------+-------------------+
| id | name                               | surname           |
+----+------------------------------------+-------------------+
|  1 | luther                             | blisset           |
|  2 | fluffy                             | bunny             |
+----+------------------------------------+-------------------+

example.php的響應邏輯為id值為x的時候,就響應第x條數據庫信息,并同時PHP錯誤回顯打開。

至此,注入環境構建完成。

網站連通性檢測

該發包的目的為網站連通性檢測,流程圖如下如所示:

網站連通性檢測流程圖

網站連通性檢測的響應,會作為原始響應(響應相似度對比技術中使用)和網站模版(網站穩定性檢測中使用)。

在具體場景中,發包情況如下圖所示:

網站連通性檢測圖

WAF探測

該發包的目的為檢測網站是否受WAF保護,流程圖如下如所示:

WAF探測流程圖

WAF探測的payload構造,在原始請求參數的基礎上,增加一個新的參數,參數值設置為帶有

AND 1=1 UNION ALL SELECT 1,NULL,'<script>alert(\"XSS\")</script>',table_name FROM information_schema.tables WHERE 2>1--/**/; EXEC xp_cmdshell('cat ../../../etc/passwd')#

載荷,通常情況下就可以觸發WAF。sqlmap檢測到與原始請求響應相似度小于0.5時,認為存在WAF。

在具體場景中(無WAF),發包情況如下圖所示:

WAF探測圖

網頁穩定性檢測

該發包的目的為檢測網頁是否穩定,流程圖如下如所示:

網頁穩定性檢測流程圖

sqlmap在檢驗網站穩定性的過程中,如果同一個請求表現出了不同的響應,那么接下來會自動識別動態內容,并在后續響應相似度對比過程中,進行動態內容移除后再進行相似度對比。

網頁穩定性檢測會進行循環的動態監測,直至動態性內容全部穩定識別之后,才會進行下一步。sqlmap識別網頁動態因子的時候,網頁動態因子存儲時候并非用的增量存儲,每一次重新請求頁面,都會進行重新計算動態因子,把之前動態因子的放棄。

在具體場景中,發包情況如下圖所示:

網頁穩定性檢測圖

在上述環境下,網頁穩定性檢測過程會發包兩次,第一次用于識別動態內容,第二次發包用于檢驗動態內容識別是否有效。對于動態響應,網頁穩定性檢測只有在準確識別動態內容的基礎上才會進行后續處理。

參數動態性檢測

該發包的目的為檢測參數是否具有動態性,流程圖如下如所示:

參數動態性檢測流程圖

sqlmap使用兩個四位數隨機數進行測試,在一些情況下,假如參數沒有表現出動態性,可以跳過檢測,該功能在批量測試時候非常有效。

重復發包問題

在sqlmap中參數動態性檢驗的過程中,兩次生成了隨機數并發包,可以理解為重復發包。針對此問題筆者也是百思不得其解,于是上Github去像作者提問,作者的回答在這里:https://github.com/sqlmapproject/sqlmap/issues/3304

sqlmap中,相同邏輯重復發包的情況也是大量存在,包括但不限于誤報檢測時的真假邏輯、union注入最后確認注入點是否可以多行注入等。筆者認為可能的原因是多發一個包確認情況避免誤報,或者是多獲得一些環境的信息(union注入多行注出)等。

在具體場景中,參數動態性檢測發包情況如下圖所示:

參數動態性檢測圖 參數動態性檢測圖

啟發式注入檢測

該發包嘗試讓Web應用報錯,目的為探測該參數點是否是動態的、是否為可能的注入點,流程圖如下如所示:

啟發式注入檢測流程圖

啟發式注入過程中,payload生成是由,'"().六種字符隨機組成的長度為10的字符串,同時滿足'和"都只有一個。啟發式注入的目的就是讓Web應用報錯,如果Web應用開啟了錯誤回顯,就可以快速識別DBMS(正則匹配)。

上圖中為啟發式注入檢測核心邏輯,除此以外還有類型轉換、XSS簡單測試等的發包,不過筆者認為這都不是核心邏輯,并且畫在圖中太復雜,就沒畫上去。

在具體場景中,發包情況如下圖所示:

參數動態性檢測圖

誤報檢測

布爾盲注中使用響應相似度分析技術來確定是否存在注入點,時間盲注中使用高斯算法來確定是否存在注入點,這兩種判斷方式存在誤報的可能,為了防止誤報,sqlmap引入誤報檢測機制。下圖為誤報檢測流程圖:

誤報檢測流程圖

在實際誤報檢測過程中,使用三個數字構成不同的邏輯,使得payload主動控制響應,并根據響應判斷注入是否真實存在。在使用上圖中特定邏輯構造payload包的過程中,就要涉及到sqlmap中測試向量中的<vector>標簽,這在后續布爾盲注和時間盲注過程中會進行詳細分析。

誤報檢測的實際發包也會在布爾盲注和時間盲注過程中進行展示和分析。

sqlmap檢測之布爾盲注

布爾盲注主要流程

布爾盲注流程圖

上圖為布爾盲注流程圖,虛線之上表示前置發包過程,虛線之下表示針對每個注入點,都會進行循環發包的流程。

在布爾盲注的前置發包過程中,可以看到有目標穩定性檢測過程,在此過程中sqlmap會找出網頁動態因素并在后續響應相似度分析過程中進行使用。

布爾盲注過程中大量使用響應相似度分析技術,從流程圖中可以看到,在針對每一個注入點循環發包時候,sqlmap第一步就是進行臨界點置空。布爾盲注中的臨界點,是在發送兩組真、假邏輯包時(邏輯假數據包先發送,邏輯真數據包后發送)的過程中確定的,其中某一個包計算后的ratio值介于0.02-0.98,那么該ratio值作為臨界點。

在常規的響應相似度分析之后,sqlmap還包括了去除HTML標簽進行注入判斷,筆者認為是針對,響應數據中HTML標簽量大,而數據庫改變數據量小的情況。此過程中也不再使用響應相似度分析,而使用集合方式(差集)來識別注入是否存在。

誤報檢測邏輯在前置發包部分已有說明,后續會針對漏洞環境的發包進行分析。

布爾盲注案列分析

在上述漏洞場景中,進行布爾盲注案例分析。

首先看一下原始請求:

example.php?id=1

布爾盲注案例圖

可以成功注入的測試向量:

<test>
    <title>AND boolean-based blind - WHERE or HAVING clause</title>
    ...
    <vector>AND [INFERENCE]</vector>
    <request>
        <payload>AND [RANDNUM]=[RANDNUM]</payload>
    </request>
    <response>
        <comparison>AND [RANDNUM]=[RANDNUM1]</comparison>
    </response>
</test>

根據測試向量,將[RANDNUM]=[RANDNUM1]隨機生成兩個數字,生成的邏輯假數據包如下:

example.php?id=1 AND 8858=3197

布爾盲注案例圖

在發送第一個邏輯假包之后,sqlmap就開始進行網頁相似度計算,首先移除動態隨機字符串之后得出邏輯假頁面與原始頁面網頁相似度值為0.787,并認為該頁面與原始頁面不相似。該網頁相似度值將會被置為本組測試向量過程中的臨界點,sqlmap默認的容差為0.05,也就是說,當一個響應的網頁相似度大于0.792(0.787+0.05)時,sqlmap認為該響應與原始頁面相似,否則,與原始頁面不相似。

根據測試向量,將[RANDNUM]=[RANDNUM]隨機生成一個數字,生成的邏輯真數據包如下:

example.php?id=1 AND 1293=1293

布爾盲注案例圖

發送邏輯真請求后,sqlmap接受響應并計算網頁相似度,此處計算網頁相似度為1(隨機字符串被移除),大于0.792,邏輯真響應與原始響應相似。

[RANDNUM]=[RANDNUM1]隨機生成兩個數字,用于確認的邏輯假數據包如下:

example.php?id=1 AND 2560=4847

布爾盲注案例圖

再一次發送邏輯假請求,去除隨機字符串后計算網頁相似度,值為0.787,認為該網頁與原始網頁不相似。至此,sqlmap認為注入存在,接下來進入誤報檢測環節。

在布爾盲注誤報檢測中,會生成三個不同的數字,并有這些數字組成不同的邏輯,把這些邏輯替換測試向量中原有的邏輯,并觀察響應是否如預期。回顧一下測試向量,其中包含一個<vector>標簽,標簽中的[INFERENCE]就是三個數字組成的邏輯替換的地方。

看一下誤報檢測流程圖,一共有五個誤報檢測邏輯,在實際情況中分別為:

example.php?id=1 AND 25=25

布爾盲注案例圖

網頁相似度值為1,與原始頁面相似。第二個邏輯:

example.php?id=1 AND 25=83

布爾盲注案例圖

網頁相似度值為0.787,與原始頁面不相似。第三個邏輯:

example.php?id=1 AND 83=53

布爾盲注案例圖

網頁相似度值為0.787,與原始頁面不相似。第四個邏輯:

example.php?id=1 AND 53=53

布爾盲注案例圖

網頁相似度值為1,與原始頁面相似。第五個邏輯:

example.php?id=1 AND 83 53

布爾盲注案例圖

網頁相似度值為0.603,與原始頁面不相似。至此,誤報檢測完成,確定注入存在。

sqlmap檢測之錯誤注入

錯誤注入主要流程

錯誤注入流程圖

上圖為錯誤注入流程圖,虛線之上表示前置發包過程,虛線之下表示針對每個注入點,都會進行循環發包的流程。

sqlmap錯誤注入并不是單純的讓數據庫服務器報錯并回顯,sqlmap是要對數據庫所報出的SQL錯誤進行控制。錯誤注入的精髓在于payload,每一個payload發包的響應都有精確的正則進行匹配。如果錯誤注入能夠成功匹配,payload中有包含SQL絕對發生執行的邏輯存在,案例分析將會詳細分析。

由于錯誤注入的識別方式中存在正則匹配,可以理解為能夠匹配的響應通常不會發生誤報,因此不需要誤報檢測。

錯誤注入案例分析

在上述漏洞場景中,進行錯誤注入案例分析。

首先看一下原始請求:

example.php?id=1

錯誤注入案例圖

可以成功注入的測試向量:

<test>
    <title>MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)</title>
    ...
    <request>
        <payload>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload>
    </request>
    <response>
        <grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
    </response>
    <details>
        <dbms>MySQL</dbms>
        <dbms_version> >= 5.0</dbms_version>
    </details>
</test>

根據測試向量,將[RANDNUM], [DELIMITER_START], [DELIMITER_STOP]按需進行替換,生成的邏輯假數據包如下:

example.php?id=1 AND (SELECT 4229 FROM(SELECT COUNT(*),CONCAT(0x7176707871,(SELECT (ELT(4229=4229,1))),0x7176627671,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)

錯誤注入案例圖

根據數據包可以看到[RANDNUM]值為4229[DELIMITER_START]在payload中值為0x7176707871,回顯時值為qvpxq[DELIMITER_STOP]在payload中值為0x7176627671,回顯時值為qvbvq

sqlmap的錯誤注入是控制注入的SQL語句報出

<b>SQL error:</b> Duplicate entry 'qvpxq1qvbvq1' for key 'group_key'<br>

這樣的錯誤,測試向量中的正則表達([DELIMITER_START](?P<result>.*?)[DELIMITER_STOP])是正好能夠提取中間的數值1。至此,錯誤注入存在。

sqlmap檢測之union注入

union注入主要流程

union注入流程圖

上圖為union注入流程圖,虛線之上表示前置發包過程,虛線之下表示針對每個注入點,都會進行循環發包的流程。

union注入是四種注入探測方式中最復雜的一種,在大的流程圖下還包括

  1. order by列數探測技術
  2. select null列數探測技術
  3. select null字符串位置確定技術

三種技術,這三種技術也包含復雜的流程和算法。單純的union注入的前置發包過程中沒有穩定性檢測的部分,也就意味著單純的union注入過程中網頁相似度對比是不會進行去重的。

union注入的流程可以分為兩步走,第一步為確定列數,以order by列數探測技術為主,select null列數探測技術為輔形成列數確定技術;第二步為在確定列數的基礎上,查找某一個字段是字符串字段,保證數據庫信息可以從該字段注出。

由于union注入的識別方式中存在正則匹配,可以理解為能夠匹配的響應通常不會發生誤報,因此不需要誤報檢測。

order by列數探測技術

order by列數探測流程圖

order by列數探測技術依賴于網頁相似度對比技術和二分差值算法。如果order by 1,響應頁面與原始頁面相似,order by 1000(隨機四位數),響應頁面與原始頁面不相似,則認為order by技術可以用于列數確定。

select null列數探測技術

select null列數探測流程圖

select null列數探測技術依賴于網頁相似度對比技術和高斯分布(正態分布),以下說明可以結合案例分析一起解讀。

select null列數探測技術在進行時,會首先指定列數猜測過程中的最大值與最小值(指定列數 最少/最小值 為1,最多/最大值 為10),sqlmap會同時發送10個數據包,包含1個NULL至10個NULL,取回10個包的響應后進行網頁相似度分析,并獲取網頁相似度數值(共10個,非True/False)。在這10個數值中,如果select null列數探測成功,那么成功那個響應的網頁相似度數值只可能是最大值或者最小值。對10個數值中去除最大值和最小值后,留下8個值,可以認為,這8個值都是列數猜測不成功返回的響應,對這個8個數據進行高斯分布建模,得出的模型就是列數猜測不成功的模型。現在使用最大值或者最小值來計算是否符合這個不成功的模型,如果符合,說明這個數據也是列數猜測不成功的響應,如果不符合,說明這個數據也是列數猜測成功的響應。

高斯分布屬于異常檢測算法的一種,以下是筆者認為理解該算法的一些關鍵點:

  • 為何要用異常檢測算法

網站的響應是基于邏輯的,如果一組請求,網站的處理邏輯相同,那么響應幾乎也是相同的。 如果某一個響應出現了變化,那么我們認為,網站處理邏輯變了,這種邏輯的變化,可能是注入成功了,因為一組請求里只有一個請求可能成功,那么這個點可以認為是異常點。

  • 建模思路

在union注入中,由于只使用網頁相似度作為建模(高斯分布)指標,那么異常值只可能在最大值或者最小值,去除掉兩個可能值之后的數據,就都是一個邏輯出來的數據(即注入不成功),使用注入不成功的數據進行高斯建模(這也是為啥select null技術猜測列數需要有最小跨度的原因,數據太少,沒法建模,數據越多,模型越準確),出來的模型就是注入不成功的模型,也就是說,服從這個模型的數據99.99%的概率是不成功的,而不服從這個分布(異常點)也就是注入成功的了。

  • union注入中為何使用相似度作為高斯建模的唯一自變量

union注入是一種回顯形式的注入攻擊,響應文本內容是union注入是否最明顯的判斷方式。由于存在諸多的類似不可控廣告這樣的噪聲內容存在,對于機器來說,使用相似度來判斷頁面內容是方便合理的。比如時間注入,使用響應時間作為分布會更合理。

  • 7個標準差代表什么

7個標準差在這里把一組數據一分為二,代表著分開的兩組數據產生于不同的機制,在這里也就是網站處理邏輯不一樣,一種是成功執行SQL語句,一種是沒有成功執行SQL語句。

select null字符串位置確定技術

select null字符串位置確定流程圖

select null字符串位置確定技術依賴于正則匹配技術,這是的union注入不需要誤報檢測流程。select null字符串位置確定的過程中,如果遇到NULL字符串無法成功找出字符串位置,那么sqlmap會自動指定一個數字替換payload中NULL字符串,并且payload的組合方式會發生改變(payload拼接在參數值后方 改為 參數值更改為一個負數,然后拼接payload),以保證指定的數字能夠回顯在響應中。

union注入案例分析

在上述漏洞場景中,進行union注入案例分析。

首先看一下原始請求:

example.php?id=1

union注入案例圖

可以成功注入的測試向量:

<test>
    <title>Generic UNION query (NULL) - 1 to 10 columns</title>
    ...
    <request>
        <payload/>
        <comment>[GENERIC_SQL_COMMENT]</comment>
        <char>NULL</char>
        <columns>1-10</columns>
    </request>
    <response>
        <union/>
    </response>
</test>

根據測試向量,我們可以知道猜測列數的最大值為10,最小值為1。此處,筆者跳過使用order by技術探測列數,使用select null技術進行列數探測。

猜測列數的范圍為1-10,因此發送10個數據包,第一個數據包:

example.php?id=1 UNION ALL SELECT NULL-- fVTK

union注入案例圖

這個數據包的網頁相似度數值為0.714,第二個數據包:

example.php?id=1 UNION ALL SELECT NULL,NULL-- jmEt

union注入案例圖

這個數據包的網頁相似度數值為0.726,第三個數據包:

example.php?id=1 UNION ALL SELECT NULL,NULL,NULL-- cRud

union注入案例圖

這個數據包的網頁相似度數值為0.834,第四個數據包:

example.php?id=1 UNION ALL SELECT NULL,NULL,NULL,NULL-- AqEV

union注入案例圖

這個數據包的網頁相似度數值為0.716,第五個數據包:

example.php?id=1 UNION ALL SELECT NULL,NULL,NULL,NULL,NULL-- NvIh

union注入案例圖

這個數據包的網頁相似度數值為0.71,第六個數據包:

example.php?id=1 UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL-- qrAS

union注入案例圖

這個數據包的網頁相似度數值為0.723,第七個數據包:

example.php?id=1 UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,NULL-- mmxs

union注入案例圖

這個數據包的網頁相似度數值為0.724,第八個數據包:

example.php?id=1 UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL-- moNa

union注入案例圖

這個數據包的網頁相似度數值為0.723,第九個數據包:

example.php?id=1 UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL-- vHbn

union注入案例圖

這個數據包的網頁相似度數值為0.725,第十個數據包:

example.php?id=1 UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL-- bVyF

union注入案例圖

這個數據包的網頁相似度數值為0.722。

得到十個網頁相似度數值,其中最大值為0.834,最小值為0.71,去除最大值最小值后,通過剩余的8個數據計算標準差為0.00430738568375,均值為0.721625。

  • 上邊界 = 均值 + 7 * 標準差 = 0.751776699786
  • 下邊界 = 均值 - 7 * 標準差 = 0.691473300214

這意味著,網頁相似度值大于上邊界或者小于下邊界,就是成功找到的列數,0.834對應的NULL的數量就是列數,為3。至此,列數探測成功。

接下來使用select null技術來確定字符串位置,三列中隨機找一個位置,插入字符串拼接語法,觀察響應是否能夠正確回顯特定字符串,數據包如下:

example.php?id=1 UNION ALL SELECT NULL,CONCAT(0x71707a7a71,0x625448774650554f4d435a696567784762446b776b5a53646c567a475259776c586a53694e675267,0x7178767671),NULL-- VdhL

union注入案例圖

可以觀察到,回顯成功。至此,字符串位置已確定,union注入存在。

sqlmap檢測之時間盲注

時間盲注主要流程

時間盲注流程圖

上圖為時間盲注流程圖,虛線之上表示前置發包過程,虛線之下表示針對每個注入點,都會進行循環發包的流程。

時間盲注過程中大量使用響應延遲判斷技術,從流程圖中可以看到,在針對每一個注入點循環發包時候,一共使用了三次響應延遲判斷技術。

誤報檢測邏輯在前置發包部分已有說明,后續會針對漏洞環境的發包進行分析。

響應延遲判斷技術

時間盲注流程圖

響應延遲判斷技術使用了高斯分布(正態分布,詳見select null列數探測技術)。在sqlmap時間盲注的測試向量庫中,有包含準確的延遲時間如[SLEEPTIME]變量和進行大量計算進行延遲的[DELAY]等兩種payload。高斯分布可以識別一個響應是否與普通響應產生于一種機制,因此,[SLEEPTIME][DELAY]就可以放在一種情況進行討論,因為salmap區分的是響應機制。

時間盲注案例分析

在上述漏洞場景中,進行時間盲注案例分析。

首先看一下原始請求:

example.php?id=1

時間盲注案例圖

可以成功注入的測試向量:

<test>
    <title>MySQL >= 5.0.12 AND time-based blind</title>
    ...
    <vector>AND [RANDNUM]=IF(([INFERENCE]),SLEEP([SLEEPTIME]),[RANDNUM])</vector>
    <request>
        <payload>AND SLEEP([SLEEPTIME])</payload>
    </request>
    <response>
        <time>[SLEEPTIME]</time>
    </response>
    <details>
        <dbms>MySQL</dbms>
        <dbms_version> >= 5.0.12</dbms_version>
    </details>
</test>

在進入正式測試之前,由于響應延遲判斷技術需要大量的正常響應作為高斯分布建模的數據,因此sqlmap會發送30次原始請求作為數據源。

根據測試向量,將[SLEEPTIME]隨機生成一個數字,生成的數據包如下:

example.php?id=1 AND SLEEP(5)

時間盲注案例圖

發送該請求后,響應發生了延遲。此時,sqlmap將[SLEEPTIME]值設置為0,生成的數據包如下:

example.php?id=1 AND SLEEP(0)

時間盲注案例圖

發送該請求后,響應未發生延遲。sqlmap將[SLEEPTIME]值設置為第一次發包的值,生成的邏輯真數據包如下:

example.php?id=1 AND SLEEP(5)

時間盲注案例圖

發送該請求后,響應發生了延遲。至此,sqlmap認為注入存在,接下來進入誤報檢測環節。

在時間盲注誤報檢測中,會生成三個不同的數字,并有這些數字組成不同的邏輯,把這些邏輯替換測試向量中原有的邏輯,并觀察響應是否如預期。回顧一下測試向量,其中包含一個<vector>標簽,標簽中的[INFERENCE]就是三個數字邏輯替換的地方。

看一下誤報檢測流程圖,一共有五個誤報檢測邏輯,在實際情況中分別為:

example.php?id=1 AND 9187=IF((19=19),SLEEP(5),9187)

時間盲注案例圖

響應發生了延遲。第二個邏輯:

example.php?id=1 AND 7052=IF((19=55),SLEEP(5),7052)

時間盲注案例圖

響應未發生延遲。第三個邏輯:

example.php?id=1 AND 1148=IF((19=58),SLEEP(5),1148)

時間盲注案例圖

響應未發生延遲。第四個邏輯:

example.php?id=1 AND 6574=IF((55=55),SLEEP(5),6574)

時間盲注案例圖

響應發生了延遲。第五個邏輯:

example.php?id=1 AND 4482=IF((58 55),SLEEP(5),4482)

時間盲注案例圖

響應未發生延遲。至此,誤報檢測完成,確定注入存在。

總結

非常感謝!能夠看到總結不易,深入研究技術也不易。希望本文對想要閱讀sqlmap源碼的人和專注于SQL注入自動化檢測的人能夠有所啟發。


Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/729/