溫馨提示×

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

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

SQL注入語(yǔ)義分析庫(kù)libinjection怎么使用

發(fā)布時(shí)間:2023-05-11 15:03:53 來(lái)源:億速云 閱讀:145 作者:iii 欄目:開(kāi)發(fā)技術(shù)

本文小編為大家詳細(xì)介紹“SQL注入語(yǔ)義分析庫(kù)libinjection怎么使用”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“SQL注入語(yǔ)義分析庫(kù)libinjection怎么使用”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來(lái)學(xué)習(xí)新知識(shí)吧。

    SQL注入語(yǔ)義分析庫(kù)libinjection

    什么是libinjection

    libinjection是一款用于防御SQL注入攻擊的開(kāi)源軟件庫(kù)。它是由C語(yǔ)言編寫的,可以嵌入到任何Web應(yīng)用程序中,并可以較為準(zhǔn)確地檢測(cè)和防止惡意SQL注入語(yǔ)句。libinjection采用了基于正則表達(dá)式的技術(shù)來(lái)識(shí)別和攔截SQL注入攻擊,同時(shí)其開(kāi)放源代碼的特點(diǎn)也使得其具備了較高的可定制性和擴(kuò)展性。

    libinjection是一個(gè)基于C語(yǔ)言的SQLi詞法解析分析器,它可以通過(guò)對(duì)不同語(yǔ)句進(jìn)行詞法分析和語(yǔ)法分析來(lái)實(shí)現(xiàn)對(duì)SQL語(yǔ)句以及HTML語(yǔ)句的解析。

    在此之前,市場(chǎng)上絕大多數(shù)的WAF都是基于正則匹配(Regex)的,很多的WAF(防火墻)以及NGWAF(下一代防火墻)出于性能方面的考慮,都會(huì)選擇使用這個(gè)庫(kù)來(lái)代替常規(guī)的正則表達(dá)式。

    ModSecurity,它是Apache和nginx的流行WAF。ModSecurity捆綁了libinjection,mod_security從2.7.4版本開(kāi)始就支持libinjection(dectectSQLi-v2.7.4、detectXSS-v2.8.0)。

    libinjection和正則表達(dá)式

    libinjection和正則表達(dá)式都是非常有效的防御SQL注入攻擊的技術(shù),但兩者之間有一些差異和優(yōu)劣。

    libinjection
    libinjection是一個(gè)專門用于檢測(cè)SQL注入攻擊的庫(kù),其使用了一個(gè)基于機(jī)器學(xué)習(xí)的算法來(lái)分析請(qǐng)求中的SQL語(yǔ)句。與正則表達(dá)式相比,它有以下優(yōu)點(diǎn):

    • 更準(zhǔn)確:libinjection使用機(jī)器學(xué)習(xí)算法分析SQL語(yǔ)句,因此可以更準(zhǔn)確地檢測(cè)SQL注入攻擊,同時(shí)減少誤報(bào)率。

    • 更容易維護(hù):libinjection的規(guī)則庫(kù)相對(duì)較小,易于維護(hù)。

    • 更快:libinjection的性能要比正則表達(dá)式好,響應(yīng)時(shí)間更短。

    正則表達(dá)式
    正則表達(dá)式是一種常見(jiàn)的用于檢測(cè)和防御各種Web應(yīng)用程序攻擊(包括SQL注入攻擊)的技術(shù)。與libinjection相比,它有以下優(yōu)點(diǎn):

    更通用:正則表達(dá)式不僅可用于檢測(cè)SQL注入攻擊,而且還可用于檢測(cè)其他類型的Web應(yīng)用程序攻擊。更靈活:正則表達(dá)式可以使用各種模式和操作符,從而可以靈活地處理各種復(fù)雜情況。更可配置性:正則表達(dá)式的規(guī)則庫(kù)可以根據(jù)實(shí)際情況進(jìn)行定制和配置。

    總體而言,libinjection可能比正則表達(dá)式更準(zhǔn)確,更容易維護(hù),并具有更快的性能,但正則表達(dá)式更通用,更靈活,具有更高的可配置性。因此,為了獲得最佳的安全性能,您可能需要考慮同時(shí)使用這兩種技術(shù)。

    modsecurity 如何使用libinjection

    下面是使用libinjection和ModSecurity進(jìn)行SQL注入檢測(cè)和預(yù)防的步驟:

    安裝ModSecurity
    安裝并配置ModSecurity,使其可以與您的Web服務(wù)器一起使用。

    安裝libinjection
    安裝libinjection并將其與ModSecurity集成。如果您使用的是Debian或Ubuntu,可以使用以下命令進(jìn)行安裝:

    sudo apt-get install libinjection-dev

    在ModSecurity中使用libinjection
    將ModSecurity配置為使用libinjection來(lái)檢測(cè)SQL注入攻擊。以下是一個(gè)示例ModSecurity規(guī)則,可用于檢測(cè)SQL注入攻擊:

    SecRule ARGS "@detectSQLi" \
        "id:1,\
        phase:2,\
        t:none,\
        t:lowercase,\
        t:replaceComments,\
        t:compressWhitespace,\
        ctl:auditLogParts=+E,\
        ctl:debugLogParts=+E,\
        ctl:requestBodyProcessor=XML,\
        ctl:ruleEngine=on,\
        ctl:auditEngine=on,\
        ctl:ruleRemoveByTag=abcd \
        ctl:ruleRemoveById=1 \
        libinjection_check"
    
    SecRule &TX:INJECTION @eq 1 \
        "id:2,\
        phase:2,\
        t:none,\
        ctl:auditLogParts=+E,\
        ctl:debugLogParts=+E,\
        ctl:requestBodyProcessor=XML,\
        ctl:ruleEngine=on,\
        ctl:auditEngine=On,\
        ctl:ruleRemoveByTag=abcd \
        ctl:ruleRemoveById=2 \
        block"

    這個(gè)規(guī)則中包含了兩個(gè)SecRule。第一個(gè)將對(duì)輸入請(qǐng)求進(jìn)行規(guī)范化和過(guò)濾,然后使用libinjection檢測(cè)SQL注入攻擊。第二個(gè)SecRule將根據(jù)檢測(cè)結(jié)果來(lái)做出相應(yīng)的動(dòng)作,例如阻止訪問(wèn)請(qǐng)求或?qū)⑵溆涗浽谌罩局小?/p>

    ModSecurity只用了libinjection防御sql注入嗎?

    ModSecurity不僅使用了libinjection,還使用了正則表達(dá)式等多種技術(shù)來(lái)進(jìn)行SQL注入攻擊防御。實(shí)際上,在ModSecurity中使用正則表達(dá)式是非常常見(jiàn)的一種方法,因?yàn)檫@種方法可以用于檢測(cè)和阻止各種類型的Web應(yīng)用程序攻擊,包括SQL注入攻擊。

    以下是一個(gè)示例ModSecurity規(guī)則,使用正則表達(dá)式檢測(cè)SQL注入攻擊:

    SecRule ARGS "@detectSQLi" \
        "id:1,\
        phase:2,\
        t:none,\
        t:lowercase,\
        t:replaceComments,\
        t:compressWhitespace,\
        ctl:auditLogParts=+E,\
        ctl:debugLogParts=+E,\
        ctl:requestBodyProcessor=XML,\
        ctl:ruleEngine=on,\
        ctl:auditEngine=on,\
        ctl:ruleRemoveByTag=abcd \
        ctl:ruleRemoveById=1 \
        libinjection_check"
    
    SecRule &TX:INJECTION @eq 1 \
        "id:2,\
        phase:2,\
        t:none,\
        ctl:auditLogParts=+E,\
        ctl:debugLogParts=+E,\
        ctl:requestBodyProcessor=XML,\
        ctl:ruleEngine=on,\
        ctl:auditEngine=On,\
        ctl:ruleRemoveByTag=abcd \
        ctl:ruleRemoveById=2 \
        block"

    雖然語(yǔ)義分析引擎能夠更準(zhǔn)確地識(shí)別和阻止惡意流量,但是正則表達(dá)式仍然是一種非常重要的檢測(cè)方式,可以用來(lái)完成一些特定的任務(wù)。

    例如,對(duì)于某些規(guī)則化的數(shù)據(jù)格式,如郵件地址、電話號(hào)碼和身份證號(hào)碼等,使用正則表達(dá)式可以快速、準(zhǔn)確地進(jìn)行匹配判斷。此外,正則表達(dá)式還可以用來(lái)檢測(cè)各種類型的注入攻擊(如SQL注入和XSS攻擊)等漏洞利用行為。

    因此,在實(shí)際的安全防御中,WAF通常會(huì)同時(shí)采用多種技術(shù)手段,包括語(yǔ)義分析引擎和正則表達(dá)式等,以提高其檢測(cè)能力,并最大程度地保護(hù)Web應(yīng)用程序免受攻擊威脅。

    WAF研發(fā)領(lǐng)域,語(yǔ)義分析相對(duì)于正則表達(dá)式先進(jìn)性的研究

    多年以來(lái),WAF對(duì)攻擊的檢測(cè),通常使用正則表達(dá)式,典型的如ModSecurity。作為老牌的WAF,其擁有龐大的正則規(guī)則庫(kù)。其檢測(cè)率高,但也正因?yàn)橐?guī)則數(shù)量龐大,正則逐一匹配,此過(guò)程速度慢,性能低。

    對(duì)于同步檢測(cè)的WAF產(chǎn)品,部署并對(duì)網(wǎng)站提供防護(hù)后,會(huì)帶來(lái)不小的訪問(wèn)性能影響。

    新興的WAF產(chǎn)品,漸有使用語(yǔ)義分析引擎取代正則表達(dá)式檢測(cè)。
    其優(yōu)勢(shì)究竟何在,性能又能提升多少?

    WAF研發(fā)領(lǐng)域,語(yǔ)義分析相對(duì)于正則表達(dá)式先進(jìn)性的研究

    libinjection架構(gòu)和使用

    SQL注入語(yǔ)義分析庫(kù)libinjection怎么使用

    官方使用示例

    #include <stdio.h>
    #include <string.h>
    #include "libinjection.h"
    
    int main(int argc, const char* argv[])
    {
        char fingerprint[8];
        const char* input;
        size_t slen;
        int issqli;
    
        if (argc < 2) {
            fprintf(stderr, "Usage: %s inputstring\n", argv[0]);
            return -1;
        }
    
        input = argv[1];
        slen = strlen(input);
    
    
        issqli = libinjection_sqli(input, slen, fingerprint);
        if (issqli) {
            printf("sqli with fingerprint of '%s'\n", fingerprint);
        } else {
            printf("not sqli\n");
        }
    
    
        return issqli;
    }

    具體的檢查sql注入實(shí)現(xiàn)為 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;
    
        /*
         * no input? not SQLi
         */
        if (slen == 0) {
            return FALSE;
        }
    
        /*
         * test input "as-is"
         */
        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 input has a single_quote, then
         * test as if input was actually '
         * example: if input if "1' = 1", then pretend it's
         *   "'1' = 1"
         * Porting Notes: example the same as doing
         *   is_string_sqli(sql_state, "'" + s, slen+1, NULL, fn, arg)
         *
         */
        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;
                }
            }
        }
    
        /*
         * same as above but with a double-quote "
         */
        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;
            }
        }
    
        /*
         * Hurray, input is not SQLi
         */
        return FALSE;
    }

    這段代碼是用于檢測(cè) SQL 注入攻擊的,通過(guò)調(diào)用 libinjection 庫(kù)對(duì)輸入的 SQL 查詢語(yǔ)句進(jìn)行指紋識(shí)別,并判斷是否存在于已知的 SQL 注入指紋庫(kù)中。

    • 首先獲取輸入字符串 s 和其長(zhǎng)度 slen。如果輸入字符串長(zhǎng)度為0,則直接返回 FALSE,不需要進(jìn)行檢測(cè)。

    • 接著,對(duì)輸入的 SQL 查詢語(yǔ)句進(jìn)行指紋識(shí)別,并標(biāo)記 FLAG_QUOTE_NONE 和 FLAG_SQL_ANSI 標(biāo)志位。然后通過(guò) sql_state->lookup 函數(shù)查找該指紋是否已經(jīng)存在于數(shù)據(jù)庫(kù)中,如果存在則返回 TRUE。

    “test input as-is” 的意思是對(duì)輸入的 SQL 語(yǔ)句進(jìn)行原樣測(cè)試,即不進(jìn)行任何轉(zhuǎn)義或處理。這相當(dāng)于將輸入的 SQL 語(yǔ)句作為一個(gè)整體進(jìn)行指紋識(shí)別,并標(biāo)記 FLAG_QUOTE_NONE 和 FLAG_SQL_ANSI 標(biāo)志位,在已知的 SQL 注入指紋庫(kù)中查找是否存在相同的指紋。如果存在,則說(shuō)明該輸入可能是 SQL 注入攻擊,否則繼續(xù)進(jìn)行其他檢測(cè)。通常情況下,如果輸入字符串包含單引號(hào)或雙引號(hào)字符或者 SQL 關(guān)鍵字,就需要進(jìn)行進(jìn)一步的檢測(cè)和處理。

    • 如果該指紋不存在于數(shù)據(jù)庫(kù)中,則嘗試將查詢語(yǔ)句解析為 MySQL 語(yǔ)法,通過(guò) reparse_as_mysql 函數(shù)進(jìn)行轉(zhuǎn)換。如果轉(zhuǎn)換成功,則再次調(diào)用 libinjection_sqli_fingerprint 函數(shù)對(duì)轉(zhuǎn)換后的 SQL 查詢語(yǔ)句進(jìn)行指紋識(shí)別,并標(biāo)記 FLAG_QUOTE_NONE 和 FLAG_SQL_MYSQL 標(biāo)志位。最后再次通過(guò) sql_state->lookup 函數(shù)查找該指紋是否存在于數(shù)據(jù)庫(kù)中,如果存在則返回 TRUE。

    • 接下來(lái),如果輸入的字符串中包含單引號(hào)字符,則調(diào)用 libinjection_sqli_fingerprint 函數(shù)對(duì) SQL 查詢語(yǔ)句進(jìn)行指紋識(shí)別,并標(biāo)記 FLAG_QUOTE_SINGLE 和 FLAG_SQL_ANSI 標(biāo)志位。然后通過(guò) sql_state->lookup 函數(shù)查找該指紋是否已經(jīng)存在于數(shù)據(jù)庫(kù)中,如果存在則返回 TRUE。

    • 如果該指紋不存在于數(shù)據(jù)庫(kù)中,則嘗試將查詢語(yǔ)句解析為 MySQL 語(yǔ)法,通過(guò) reparse_as_mysql 函數(shù)進(jìn)行轉(zhuǎn)換。如果轉(zhuǎn)換成功,則再次調(diào)用 libinjection_sqli_fingerprint 函數(shù)對(duì)轉(zhuǎn)換后的 SQL 查詢語(yǔ)句進(jìn)行指紋識(shí)別,并標(biāo)記 FLAG_QUOTE_SINGLE 和 FLAG_SQL_MYSQL 標(biāo)志位。最后再次通過(guò) sql_state->lookup 函數(shù)查找該指紋是否存在于數(shù)據(jù)庫(kù)中,如果存在則返回 TRUE。

    • 最后,如果輸入的字符串中包含雙引號(hào)字符,則調(diào)用 libinjection_sqli_fingerprint 函數(shù)對(duì) SQL 查詢語(yǔ)句進(jìn)行指紋識(shí)別,并標(biāo)記 FLAG_QUOTE_DOUBLE 和 FLAG_SQL_MYSQL 標(biāo)志位。然后通過(guò) sql_state->lookup 函數(shù)查找該指紋是否已經(jīng)存在于數(shù)據(jù)庫(kù)中,如果存在則返回 TRUE。

    • 如果輸入字符串沒(méi)有被識(shí)別為 SQL 注入攻擊,則最后返回 FALSE。

    總結(jié),這段代碼是用于檢測(cè) SQL 注入攻擊,通過(guò)指紋識(shí)別技術(shù)來(lái)進(jìn)行檢測(cè)和防御。同時(shí)支持 ANSI SQL 和 MySQL 兩種語(yǔ)法,并能夠檢測(cè)包含單引號(hào)和雙引號(hào)字符以及 SQL 關(guān)鍵字的字符串。

    例如,輸入常用的SQL注入的檢測(cè)語(yǔ)句 :&rsquo; and 1=1
    libinjection會(huì)將其轉(zhuǎn)換為s&1,其中單引號(hào)依據(jù)定義被轉(zhuǎn)換為s,and被轉(zhuǎn)換為&,數(shù)字被轉(zhuǎn)換為1。

    libinjection在轉(zhuǎn)換完后,通過(guò)二分查找算法對(duì)內(nèi)置的特征進(jìn)行匹配,匹配到則將SQL注入識(shí)別特征復(fù)制進(jìn)fingerprint變量并返回。

    轉(zhuǎn)換 搜索關(guān)鍵字: sql_keywords ,在文件libinjection_sqli_data.h 中~!

    在libinjection中,將SQL關(guān)鍵字轉(zhuǎn)換為單個(gè)字母時(shí)使用的字符集通常是a-z或A-Z。這意味著只有26個(gè)不同的字母可以用來(lái)表示所有的SQL關(guān)鍵字。

    為了解決這個(gè)問(wèn)題**,libinjection使用了一些技巧來(lái)擴(kuò)展字母表的大小。其中一個(gè)技巧是引入數(shù)字后綴。例如,對(duì)于兩個(gè)關(guān)鍵字SELECT和SET,它們都會(huì)被轉(zhuǎn)換為字母s。為了避免沖突,第二個(gè)關(guān)鍵字SET會(huì)被轉(zhuǎn)換為字母s2。**

    另一個(gè)技巧是使用大寫字母表示特殊的關(guān)鍵字。例如,LIMIT和OFFSET是MySQL和PostgreSQL中常用的關(guān)鍵字,它們被分別映射為L(zhǎng)和O。這樣做的好處是,即使一個(gè)關(guān)鍵字被映射為小寫字母,仍然可以通過(guò)使用大寫字母來(lái)表示其他特殊關(guān)鍵字,以避免沖突。

    需要注意的是,雖然僅有26個(gè)字母可以用來(lái)表示所有的SQL關(guān)鍵字,但由于上面提到的技巧,libinjection能夠支持更多的關(guān)鍵字,并確保每個(gè)關(guān)鍵字都使用唯一的單個(gè)字母來(lái)表示。

    讀到這里,這篇“SQL注入語(yǔ)義分析庫(kù)libinjection怎么使用”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過(guò)才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

    向AI問(wèn)一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI