安全研究所 | 突破語(yǔ)義分析的黑魔法

當(dāng)下,語(yǔ)義分析算法因其輕規(guī)則、低誤漏報(bào)、更貼合業(yè)務(wù)場(chǎng)景等優(yōu)勢(shì)被廣泛應(yīng)用于各類型的安全防護(hù)產(chǎn)品中,并取得了較好的效果,但現(xiàn)階段依舊存在一些方法能夠有效突破傳統(tǒng)語(yǔ)義分析防護(hù),本文會(huì)介紹部分SQL注入場(chǎng)景下突破語(yǔ)義分析算法的黑魔法。
詞法分析
現(xiàn)階段,SQL注入的詞法分析主流分為兩類:
基于弱規(guī)則詞法黑名單
基于詞法Token變化
其中基于弱規(guī)則詞法黑名單的算法被用于大家熟知的Libinjection,主要通過(guò)將用戶的輸入進(jìn)行Token化,然后再去匹配一份維護(hù)好了的SQL注入黑名單規(guī)則庫(kù),從而有效發(fā)現(xiàn)SQL注入問(wèn)題。
其中各種輸入對(duì)應(yīng)詞法如下:
檢測(cè)SQL注入的流程如下:
而基于Token變化的檢測(cè)算法,規(guī)則比上述算法更弱,只需計(jì)算用戶的輸入是否橫跨了多個(gè)Token,如果橫跨了多個(gè)Token則判斷為存在SQL注入。
語(yǔ)義分析
和詞法分析相比,語(yǔ)義分析會(huì)做的更加細(xì)致,它不僅僅關(guān)注SQL的Token,更會(huì)去關(guān)注用戶的輸入對(duì)具體的SQL結(jié)構(gòu)造成了怎樣的改變,這樣能夠更大程度的解決詞法分析僅僅基于Token造成的誤報(bào)問(wèn)題。
當(dāng)用戶輸入會(huì)導(dǎo)致SQL整體語(yǔ)義發(fā)生變化,往往會(huì)被語(yǔ)義分析判定為SQL注入。
對(duì)于一些運(yùn)行時(shí)安全防護(hù)產(chǎn)品而言,由于運(yùn)行在應(yīng)用中,可以直接獲取到完整的SQL語(yǔ)句,語(yǔ)義分析的準(zhǔn)確率往往較高,而對(duì)于傳統(tǒng)流量型安全防護(hù)產(chǎn)品而言,由于只能獲取到流量中的用戶輸入?yún)?shù),無(wú)法知道真實(shí)運(yùn)行的SQL語(yǔ)句是什么樣的,就需要額外的工作,大體分為兩類:
SQL片段分析:
需要基于 Context Free Grammer ,最大的挑戰(zhàn)是時(shí)間復(fù)雜度和準(zhǔn)確率。
構(gòu)造完整的SQL語(yǔ)句:
主流安全產(chǎn)品會(huì)假設(shè)用戶輸入?yún)?shù)為數(shù)字型、字符型兩種場(chǎng)景,將參數(shù)拼接到簡(jiǎn)化的SQL語(yǔ)句中構(gòu)成完整的SQL語(yǔ)句,進(jìn)而進(jìn)行語(yǔ)義分析。但很多時(shí)候會(huì)出現(xiàn)關(guān)鍵字拼接參數(shù)(如IN、GROUP BY、ORDER BY等)的場(chǎng)景,這種情況下語(yǔ)義分析準(zhǔn)確率就會(huì)下降,而如果盡可能的窮舉了用戶參數(shù)的拼接場(chǎng)景,則會(huì)造成性能的不可控。
預(yù)期外的SQL特性
原理
語(yǔ)義分析會(huì)面臨的一個(gè)最大的難題就是:雖然大部分的數(shù)據(jù)庫(kù)語(yǔ)法都比較相似,但不同數(shù)據(jù)庫(kù)之間又都有自己獨(dú)有的一些特性在里面,這樣如果攻擊者對(duì)某一款數(shù)據(jù)庫(kù)足夠了解,就可能通過(guò)一些特殊的SQL特性進(jìn)行SQL注入,而語(yǔ)義分析之前又未能兼容該特性,從而導(dǎo)致語(yǔ)義分析引擎報(bào)錯(cuò),失去檢測(cè)能力。
巧用ODBC
ODBC是一個(gè)大部分SQL都支持的特性,官方介紹如下:
{identifier expr} is ODBC escape syntax and is accepted for ODBC compatibility. The value is expr. The { and } curly braces in the syntax should be written literally; they are not metasyntax as used elsewhere in syntax descriptions.
由于ODBC本身的自由性,可以構(gòu)造出很多非常復(fù)雜的SQL語(yǔ)句,從而導(dǎo)致語(yǔ)義分析很難進(jìn)行識(shí)別。
psql并不認(rèn)識(shí)轉(zhuǎn)義字符
幾乎大部分主流語(yǔ)義分析引擎、主流數(shù)據(jù)庫(kù)都將 \ 理解為轉(zhuǎn)義字符,但PSQL并不這么理解,對(duì) \ 理解上的差異使得繞過(guò)PSQL變得十分容易。
神奇的科學(xué)計(jì)數(shù)法
科學(xué)符號(hào),特別是 e 符號(hào),已被集成到包括 SQL 在內(nèi)的許多編程語(yǔ)言中。目前還不清楚這是否是所有 SQL 實(shí)現(xiàn)的一部分,但它是 MySQL/MariaDB 實(shí)現(xiàn)的一部分。當(dāng)e符號(hào)在無(wú)效的上下文中使用的時(shí)候,并不會(huì)導(dǎo)致SQL報(bào)錯(cuò),而是會(huì)被SQL自行忽略,這就導(dǎo)致了SQL注入時(shí)的Payload可以通過(guò)大量無(wú)效科學(xué)符號(hào)來(lái)影響語(yǔ)義分析引擎對(duì)SQL語(yǔ)句的解析。
select last_name from students where student_id = '1' union select concat 5.e(1.e(flag 10.2e)3.e,'***'6.e) from test 1.e.flag--
注釋欺騙的藝術(shù)
原理
大部分語(yǔ)義分析往往都是能夠識(shí)別出注釋,并在分析時(shí)省略注釋后面語(yǔ)句的分析,從而實(shí)現(xiàn)更好的性能,那么如果攻擊者能夠成功構(gòu)造出語(yǔ)義分析引擎認(rèn)為是注釋而實(shí)際數(shù)據(jù)庫(kù)并不認(rèn)為是注釋的特殊關(guān)鍵字,再把攻擊的Payload隱藏在注釋之后,就能成功欺騙語(yǔ)義分析,光明正大的進(jìn)行SQL注入。
萬(wàn)能注釋 //
存在不少語(yǔ)義分析引擎,在解析數(shù)據(jù)流的時(shí)候,會(huì)將 // 作為注釋處理,忽視后面的內(nèi)容,而大部分主流數(shù)據(jù)庫(kù),并不將 // 作為注釋。
注釋結(jié)束符的差別
語(yǔ)義分析引擎 往往認(rèn)為 \r \n 都是注釋的結(jié)束符,但很多數(shù)據(jù)庫(kù)(MYSQL\ORACLE等)只認(rèn) 為 \n 是注釋結(jié)束符,利用注釋結(jié)束符理解的差異可以構(gòu)造繞過(guò)。
mybatis眼中的#
JAVA的mybatis框架會(huì)對(duì)用戶輸入的參數(shù)做一些特殊的處理,尤其針對(duì)形如 #{param} 這種寫法的數(shù)據(jù)的額外處理,會(huì)對(duì)語(yǔ)義分析造 成極強(qiáng)的欺騙性。
巧用特殊關(guān)鍵字
原理
除去讓很多開(kāi)發(fā)、安全人員熟知的關(guān)鍵字外,不少數(shù)據(jù)庫(kù)也擁有一些較為冷門的關(guān)鍵字,這些關(guān)鍵字在語(yǔ)義分析或詞法分析時(shí)很可能未能兼容,從而導(dǎo)致防護(hù)失效。因此,尋找冷門且有效的關(guān)鍵字也是繞過(guò)語(yǔ)義分析引擎的一種有效手段,尤其是針對(duì)新版本的數(shù)據(jù)庫(kù),往往會(huì)出現(xiàn)一些新的關(guān)鍵字,這些關(guān)鍵字極有可能未被兼容。
handle替代select
MySQL 除了可以使用 select 查詢表中的數(shù)據(jù),也可使用 handler 語(yǔ)句,這條語(yǔ)句使我們能夠一行一行的瀏覽一個(gè)表中的數(shù)據(jù)。它是 MySQL專用的語(yǔ)句,并沒(méi)有包含到SQL標(biāo)準(zhǔn)中。handler 語(yǔ)句由于可以查詢數(shù)據(jù),因此也是SQL注入中一個(gè)十分方便且鮮為人知的關(guān)鍵字。
SELECT * FROM students WHERE stuname = 'glassy';Handler flag OPEN;Handler flag read first;Handler flag close;#
MEMBER OF函數(shù)
MEMBER OF()是一個(gè)MySQL8高版本特性,官方定義它是一個(gè)函數(shù),但是這個(gè)函數(shù)的函數(shù)名中間還包含空格,十分具有欺騙性,雖然它對(duì)于注出數(shù)據(jù)并沒(méi)有什么幫助,但是放在注入Payload的前段以促使語(yǔ)義分析引擎解析失敗報(bào)錯(cuò)卻是一個(gè)很不錯(cuò)的選擇。
SELECT last_name FROM students WHERE student_id = '1' and (select substr((SELECT flag from flag), 1, 1) MEMBER OF('["a","b","t"]'))=1;
[免責(zé)聲明]
原文標(biāo)題: 安全研究所 | 突破語(yǔ)義分析的黑魔法
本文由作者原創(chuàng)發(fā)布于36氪企服點(diǎn)評(píng);未經(jīng)許可,禁止轉(zhuǎn)載。




