溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何分析SQL注入語義分析庫Libinjection

發布時間:2021-11-18 15:04:05 來源:億速云 閱讀:309 作者:柒染 欄目:網絡管理

如何分析SQL注入語義分析庫Libinjection,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

一、前言

這次主要講開源SQL注入語義分析庫libinjection,如果有發現其他開源SQL語義分析庫的歡迎告知。libinjection的程序分析由Simon友情提供,需要看完整報告的可以加群看。

二、libinjection程序分析    

如何分析SQL注入語義分析庫Libinjection

從流程圖上看,libinjection首先是初始化issqlii變量,接著設置數據結構并初始化變量state,libinjection_sqli_init()函數將初始化SQL檢測所需的結構體,之后通過libinjection_is_sqli()函數進行具體分析,如果存在issqli,則將SQL注入識別特征復制進fingerprint變量并返回,如果不存在則將fingerprint變量設置為空并返回。    

如何分析SQL注入語義分析庫Libinjection

上圖是總的函數關系圖,libinjection_sqli_init()函數的主要工作是將    SQL注入識別特征碼(指紋)加載進結構體,并完成各種內置變量的初始化。libinjection_is_sqli()的處理代碼如下,根據代碼來分析        

int libinjection_is_sqli(struct libinjection_sqli_state * sql_state)
{
    const char *s = sql_state->s;
    size_t slen = sql_state->slen;

    if (slen == 0) {
        return FALSE;
    }

    libinjection_sqli_fingerprint(sql_state, FLAG_QUOTE_NONE | FLAG_SQL_ANSI);
    if (sql_state->lookup(sql_state, LOOKUP_FINGERPRINT,
                          sql_state->fingerprint, strlen(sql_state->fingerprint))) {
        return TRUE;
    } else if (reparse_as_mysql(sql_state)) {
        libinjection_sqli_fingerprint(sql_state, FLAG_QUOTE_NONE | FLAG_SQL_MYSQL);
        if (sql_state->lookup(sql_state, LOOKUP_FINGERPRINT,
                              sql_state->fingerprint, strlen(sql_state->fingerprint))) {
            return TRUE;
        }
    }

    if (memchr(s, CHAR_SINGLE, slen)) {
        libinjection_sqli_fingerprint(sql_state, FLAG_QUOTE_SINGLE | FLAG_SQL_ANSI);
        if (sql_state->lookup(sql_state, LOOKUP_FINGERPRINT,
                              sql_state->fingerprint, strlen(sql_state->fingerprint))) {
            return TRUE;
        } else if (reparse_as_mysql(sql_state)) {
            libinjection_sqli_fingerprint(sql_state, FLAG_QUOTE_SINGLE | FLAG_SQL_MYSQL);
            if (sql_state->lookup(sql_state, LOOKUP_FINGERPRINT,
                                  sql_state->fingerprint, strlen(sql_state->fingerprint))) {
                return TRUE;
            }
        }
    }

    if (memchr(s, CHAR_DOUBLE, slen)) {
        libinjection_sqli_fingerprint(sql_state, FLAG_QUOTE_DOUBLE | FLAG_SQL_MYSQL);
        if (sql_state->lookup(sql_state, LOOKUP_FINGERPRINT,
                              sql_state->fingerprint, strlen(sql_state->fingerprint))) {
            return TRUE;
        }
    }

    return FALSE;
}

1.判斷用戶輸入的字符串長度是否合法,為零則返回FALSE。(即沒有發現SQL注入)

2.執行SQL注入識別函數(libinjection_sqli_fingerprint,無引號,標準SQL語法),獲取字符串識別特征碼

3.執行結構體內的查詢函數(這里為libinjection_sqli_lookup_word,二分查找算法),對比第二步獲取的識別特征是否與SQL注入識別特征匹配。

4.如果第三步發現SQL注入特征匹配結果為真,則返回true,并將SQL注入識別特征匹配到的fingerprint寫入結構體,

5.如果檢測失敗,則調用reparse_as_mysql()函數判斷是否存在“(dash-dash-[notwhite]) 注釋”或“'#' 運算符號”,如果存在則再次執行SQL識別函數(libinjection_sqli_fingerprint,無引號,MYSQL語法),

6. 同時執行結構體的分析函數(libinjection_sqli_lookup_word,二分查找算法)進行特征匹配檢測,如果結果為真,則返回true,并將SQL注入識別特征匹配到的fingerprint寫入結構體。

7.如果前面的判斷沒有返回結果,將掃描參數(即用戶輸入的字符串)查找是否存在單

引號。如果為真接著重復上述檢測步驟。

8.如果前面的判斷依舊沒有返回結果,將掃描參數(即用戶輸入的字符串)查找是否存

在雙引號。如果為真則接著執行SQL注入識別函數

(libinjection_sqli_fingerprint,雙引號,MYSQL語法)

同時執行結構體的分析函數(libinjection_sqli_lookup_word,二分查找算法)進行特征匹配檢測結果為真,則返回true,并將SQL注入識別特征匹配到的fingerprint寫入結構體。

9.如果前面三種判斷均無結果則默認該參數(用戶輸入的字符串)不存在SQL注入。

三、libinjection實例分析

上面已經對libinjection的程序進行了簡單的分析,下面通過一個具體的例子來了解libinjecton的處理流程。

首先來看libinjection對特征碼的定義

typedef enum {
    TYPE_NONE        = 0   /*無實際意義,僅對位數進行填充*/
    , TYPE_KEYWORD     = (int)'k'  /*例如COLUMN,DATABASES,DEC等會被識別為該值*/
    , TYPE_UNION       = (int)'U'  /*EXCEPT,INTERSECT,UNION等會被識別為該值*/
    , TYPE_GROUP       = (int)'B'    /*GROUP BY,LIMIT,HAVING*/
    , TYPE_EXPRESSION  = (int)'E'   /*INSERT,SELECT,SET*/
    , TYPE_SQLTYPE     = (int)'t'  /*SMALLINT,TEXT,TRY*/
    , TYPE_FUNCTION    = (int)'f'   /*UPPER,UTL_HTTP.REQUEST,UUID*/
    , TYPE_BAREWORD    = (int)'n'  /*WAITFOR,BY,CHECK*/
    , TYPE_NUMBER      = (int)'1'   /*所有數字會被識別為1*/
    , TYPE_VARIABLE    = (int)'v'  /*CURRENT_TIME,LOCALTIME,NULL*/
    , TYPE_STRING      = (int)'s'   /*單引號和雙引號*/
    , TYPE_OPERATOR    = (int)'o'  /*+=,-=,!>*/
    , TYPE_LOGIC_OPERATOR = (int)'&'   /*&&,AND,OR*/
    , TYPE_COMMENT     = (int)'c'     /*注釋符*/
    , TYPE_COLLATE     = (int)'A'  /* COLLATE*/
    , TYPE_LEFTPARENS  = (int)'('     
    , TYPE_RIGHTPARENS = (int)')'  /* not used? */
    , TYPE_LEFTBRACE   = (int)'{'    
    , TYPE_RIGHTBRACE  = (int)'}'
    , TYPE_DOT         = (int)'.'
    , TYPE_COMMA       = (int)','
    , TYPE_COLON       = (int)':'
    , TYPE_SEMICOLON   = (int)';'
    , TYPE_TSQL        = (int)'T'  /* TSQL start */ /*DECLARE,DELETE,DROP*/
    , TYPE_UNKNOWN     = (int)'?'
    , TYPE_EVIL        = (int)'X'  /* unparsable, abort  */   /* “/*!*/”  */
    , TYPE_FINGERPRINT = (int)'F'  /* not really a token */
    , TYPE_BACKSLASH   = (int)'\\'
} sqli_token_types;

libinjection將輸入的數據依據上述的定義進行轉換,之后就會得到SQL注入識別特征,或者說指紋,然后通過二分查找算法,在特征庫中進行匹配,匹配到則報SQL注入漏洞。

例如:

我們輸入SQL注入的檢測語句

‘ and 1=1

libinjection會將其轉換為s&1,其中單引號依據定義被轉換為s,and被轉換為&,數字被轉換為1

' UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL--

libinjection會將其轉換為sUEvc,其中單引號依據定義被轉換為s,UNION ALL被轉換為U,SELECT被轉換為E,NULL被轉換為v,后面相同的NULL合并為一個v,--注釋符被轉換為c

libinjection在轉換完后,通過二分查找算法對內置的8000多個特征進行匹配,匹配到則將SQL注入識別特征復制進fingerprint變量并返回。

通過上述兩個例子就可以知道libinjection對數據的轉換邏輯,其中針對一些特殊情況會有特殊處理,文章篇幅有限這里不講,有興趣可以去看代碼。

四、總結

SQL注入語義分析庫libinjection相比傳統正則匹配識別SQL注入的好處在于速度快以及低誤報,低漏報 。

速度快體現在該庫全程比較耗性能的就一二分查找算法,相對于正則對性能的消耗來說可以忽略不計,這點從火焰圖上可以很明顯的看出來,所以無論特征數是800,8000還是80000,對處理速度來說都不會有太大影響,而正則匹配規則達到千條以上就能明顯感覺到性能的變化。

低誤報呢,以前在測試modsecurity2.0的owasp規則的時候,那個誤報率簡直感人。但是如果要把規則寫細,降低誤報率的話,那規則數必然會上去進而對性能產生一些影響。SQL注入語義好就好在,要想滿足他的匹配規則,一般來說必須滿足三個特征以上,比如s&1或者sUEvc,而每個特征要么是特殊字符,要么是SQL語句的保留字,所以正常情況下用戶輸入,很少會出現這種誤報這種情況。

關于如何分析SQL注入語義分析庫Libinjection問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女