周 穎,方 勇,黃 誠(chéng),劉 亮
(1.四川大學(xué) 電子信息學(xué)院,成都 610065; 2.四川大學(xué) 網(wǎng)絡(luò)空間安全學(xué)院,成都 610207)(*通信作者電子郵箱opcodesec@gmail.com)
隨著互聯(lián)網(wǎng)技術(shù)的高速發(fā)展,Web應(yīng)用程序在人類(lèi)生活發(fā)展中起到重要的媒介和資產(chǎn)管理作用。然而由于開(kāi)發(fā)人員安全意識(shí)不足,全球大部分網(wǎng)站遭受了不同程度的Web攻擊。據(jù)2016年中國(guó)網(wǎng)站安全漏洞形勢(shì)分析報(bào)告[1],SQL(Structured Query Language)注入[2]攻擊占據(jù)漏洞類(lèi)型的44.9%,占網(wǎng)站衛(wèi)士攔截攻擊類(lèi)型的39.8%;而且Web應(yīng)用一旦被發(fā)現(xiàn)SQL注入漏洞,容易形成通用漏洞,威脅范圍廣泛,影響巨大。所以,為保護(hù)互聯(lián)網(wǎng)信息安全,SQL注入行為檢測(cè)是至關(guān)重要的一個(gè)環(huán)節(jié)。PHP(Hypertext Preprocessor)作為一個(gè)優(yōu)秀的腳本語(yǔ)言,由于其開(kāi)發(fā)周期短、成本低和豐富的擴(kuò)展資源等優(yōu)秀特性,在Web技術(shù)上已成為主流。據(jù)2016年Web漏洞統(tǒng)計(jì)[3],87%的漏洞對(duì)應(yīng)的開(kāi)發(fā)語(yǔ)言為PHP,那么,在PHP應(yīng)用程序中,檢測(cè)SQL注入行為愈顯重要。
對(duì)于SQL注入行為檢測(cè)技術(shù),國(guó)內(nèi)外學(xué)者進(jìn)行了如下研究。Kar等[4]提出基于文檔相似性匹配的檢測(cè)方法,在最常發(fā)生SQL注入的位置提取子句,建立惡意子句的哈希庫(kù);由于在實(shí)際應(yīng)用中發(fā)生SQL注入的位置較多,難以建立起覆蓋面較全的惡意子句庫(kù)。趙宇飛等[5]以網(wǎng)絡(luò)流量作為數(shù)據(jù)源,從網(wǎng)絡(luò)環(huán)境中提取惡意請(qǐng)求較正常請(qǐng)求流量中有較大區(qū)別的特征檢測(cè)SQL注入;但該檢測(cè)方法缺乏SQL注入行為的針對(duì)性,容易將其他攻擊行為誤判為SQL注入行為。由于SQL語(yǔ)句的上下文無(wú)關(guān)性,惡意語(yǔ)句和正常語(yǔ)句在語(yǔ)義和語(yǔ)法上有較明顯的區(qū)別,因此,語(yǔ)法分析技術(shù)被應(yīng)用在SQL注入行為的檢測(cè)中。Priyaa等[6]運(yùn)用支持向量機(jī)(Supported Vector Machine, SVM)分類(lèi)算法檢測(cè)SQL注入,通過(guò)片段化的SQL語(yǔ)法樹(shù),提取語(yǔ)法和語(yǔ)義特征建立多維特征向量,訓(xùn)練SVM分類(lèi)器。該方法的數(shù)據(jù)來(lái)源為數(shù)據(jù)庫(kù)日志,由于數(shù)據(jù)庫(kù)日志缺少訪問(wèn)者信息,因此該方法并不適用于攻擊溯源。傳統(tǒng)的基于Web日志[7]的SQL注入檢測(cè)技術(shù),將日志中的訪問(wèn)信息作為SQL注入檢測(cè)憑證時(shí),由于信息的不完整性,無(wú)法判斷用戶(hù)輸入是否進(jìn)入數(shù)據(jù)庫(kù)層。對(duì)于PHP應(yīng)用程序,污點(diǎn)分析技術(shù)被應(yīng)用于SQL注入行為檢測(cè)中,分為基于不可信源[8]和可信源[9]進(jìn)行污點(diǎn)分析,通過(guò)污點(diǎn)分析技術(shù),能夠定位SQL語(yǔ)句中外部輸入點(diǎn)。上述文獻(xiàn)在實(shí)現(xiàn)異常檢測(cè)中,只通過(guò)檢測(cè)不可信源中的攻擊關(guān)鍵詞等單一特征,并使用規(guī)則性的檢測(cè)方法,存在較高誤報(bào)率。上述文獻(xiàn)在進(jìn)行污點(diǎn)標(biāo)記時(shí),對(duì)每個(gè)字符都進(jìn)行來(lái)源標(biāo)記,這種標(biāo)記方法為其后分詞添加了大量不確定性;過(guò)多的污點(diǎn)標(biāo)記和污點(diǎn)凈化,難免對(duì)正常的業(yè)務(wù)邏輯產(chǎn)生影響。通常產(chǎn)生SQL注入的外部輸入點(diǎn)有限,若是對(duì)所有可信源進(jìn)行標(biāo)記將產(chǎn)生大量冗余操作,并使服務(wù)器負(fù)載較大。
為提高SQL注入行為檢測(cè)的有效性和準(zhǔn)確率,基于PHP應(yīng)用程序,本文將污點(diǎn)分析和日志分析技術(shù)相結(jié)合,進(jìn)行了如下研究工作。
1)本文基于PHP擴(kuò)展技術(shù)[10],重寫(xiě)PHP原生方法,在代碼層對(duì)SQL語(yǔ)句執(zhí)行函數(shù)進(jìn)行監(jiān)聽(tīng),對(duì)不可信源進(jìn)行屬性標(biāo)記以實(shí)現(xiàn)對(duì)攻擊者可控點(diǎn)的跟蹤,不影響變量存取過(guò)程。
2)本文基于抽象語(yǔ)法樹(shù)[11]和SQL語(yǔ)法,將污點(diǎn)標(biāo)記技術(shù)[12]應(yīng)用于詞法分析和語(yǔ)法分析中,實(shí)現(xiàn)SQL語(yǔ)句和內(nèi)部污點(diǎn)的抽象化。
3)本文通過(guò)對(duì)語(yǔ)法樹(shù)中的污點(diǎn)節(jié)點(diǎn)進(jìn)行分析,基于詞法、語(yǔ)法和語(yǔ)義,提取了SQL注入語(yǔ)句區(qū)別于正常語(yǔ)句的多方面特征,并使用機(jī)器學(xué)習(xí)方法,實(shí)現(xiàn)了SQL注入行為檢測(cè)模型。
本文提出了基于污點(diǎn)分析的SQL注入行為檢測(cè)模型,模型設(shè)計(jì)如圖1所示。
圖1 模型設(shè)計(jì)圖
按以下流程進(jìn)行SQL注入行為檢測(cè):
1)信息提取過(guò)程。
外部輸入進(jìn)入PHP應(yīng)用程序,在PHP代碼編譯時(shí),通過(guò)PHP擴(kuò)展獲取包含外部輸入的SQL語(yǔ)句、外部變量和攻擊者請(qǐng)求頭信息,并將上述信息按格式存入日志文件。
2)污點(diǎn)標(biāo)記過(guò)程。
從日志文件中讀取SQL語(yǔ)句和外部變量,生成污點(diǎn)標(biāo)記源,經(jīng)過(guò)污點(diǎn)標(biāo)記后,生成污點(diǎn)語(yǔ)法樹(shù)。
3)異常檢測(cè)模型。
基于污點(diǎn)語(yǔ)法樹(shù),提取污點(diǎn)子樹(shù)和詞法兩類(lèi)特征,選擇隨機(jī)森林算法[13]對(duì)SQL注入行為和正常行為進(jìn)行分類(lèi)訓(xùn)練,得出異常檢測(cè)模型。對(duì)異常檢測(cè)模型篩選出的SQL注入行為,記錄其攻擊載荷(payload)和攻擊者信息。
通過(guò)對(duì)圖2攻擊語(yǔ)句流動(dòng)分析可知,攻擊語(yǔ)句作為HTTP(HyperText Transfer Protocol)請(qǐng)求參數(shù)傳入服務(wù)器,經(jīng)由服務(wù)端代碼渲染后,傳遞給SQL函數(shù),最終在數(shù)據(jù)庫(kù)中執(zhí)行。在PHP應(yīng)用程序中,可通過(guò)擴(kuò)展技術(shù)在代碼層獲取SQL語(yǔ)句、外部變量和攻擊者信息。
圖2 攻擊語(yǔ)句流動(dòng)圖
對(duì)于上述信息,本文通過(guò)內(nèi)核提供的“PG(http_globals)”對(duì)攻擊者可控點(diǎn)進(jìn)行請(qǐng)求初始化。定義全局?jǐn)?shù)組存取外部變量和外部變量來(lái)源,當(dāng)攻擊者可控全局變量被賦值,將信息依次存入數(shù)組中,以數(shù)組索引值對(duì)該變量進(jìn)行外部標(biāo)記。重寫(xiě)PHP基礎(chǔ)函數(shù)中的字符串類(lèi)和解碼類(lèi),當(dāng)傳入?yún)?shù)帶有外部標(biāo)記,將標(biāo)記轉(zhuǎn)移給返回值,并以標(biāo)記值作為索引覆蓋上述數(shù)組中的值。對(duì)OPCODE(Operation Code)[14]中函數(shù)執(zhí)行類(lèi)“DO_FCALL”和“DO_FCALL_BY_NAME”自定義處理函數(shù)。在處理函數(shù)中監(jiān)控SQL函數(shù)調(diào)用,當(dāng)傳入?yún)?shù)帶有外部標(biāo)記,記錄該SQL語(yǔ)句。從全局變量“SERVER”中可獲取攻擊者請(qǐng)求頭信息,以IP地址(Internet Protocol Address)、用戶(hù)代理(User-Agent)、HTTP cookie(Cookie)、當(dāng)前時(shí)間戳(Timestamp)作為攻擊者的標(biāo)識(shí)參數(shù),使用MurmurHash算法對(duì)以上參數(shù)加密,得到識(shí)別攻擊者的Hash值。
通過(guò)“php_log_err”接口,將上述信息存入日志文件,如表1所示。對(duì)于日志中的內(nèi)容,以攻擊者Hash作為請(qǐng)求區(qū)分點(diǎn),對(duì)日志中記錄的信息進(jìn)行處理。如圖3所示,將外部變量中的元素代入SQL語(yǔ)句中進(jìn)行匹配,對(duì)匹配到的內(nèi)容使用上文中的Hash值進(jìn)行首尾標(biāo)記,作為觀測(cè)點(diǎn)。將帶觀測(cè)點(diǎn)的SQL語(yǔ)句作為污點(diǎn)標(biāo)記源。
表1 日志保存的信息
圖3 污點(diǎn)標(biāo)記源生成圖
對(duì)污點(diǎn)標(biāo)記源作語(yǔ)法分析,以主要SQL保留字作為樹(shù)枝節(jié)點(diǎn),對(duì)樹(shù)枝節(jié)點(diǎn)分別描述語(yǔ)法規(guī)則[15]。以“SELECT”為例,一條完整的“SELECT”語(yǔ)句將引用“WHERE”“GROUP BY”等其他保留字語(yǔ)法規(guī)則,其語(yǔ)法規(guī)則如下:
SELECT[ALL|DISTINCT|DISTINCTROW|TOP]
{*|table.*|[table.]col[AS alias1][,[table.]field2[AS alias2][,…]]}
[FROM table_expr[,…][IN external_database] [WHERE condition_expr operator condition_expr]
[GROUP BY group_by_expr]
[HAVING condition_expr operator condition_expr]
[ORDER BY condition_expr [ACS|DESC]]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[PROCEDURE procedure_name(argument_list)]
[FOR UPDATE|LOCK IN SHARE MODE]]
語(yǔ)法樹(shù)建立過(guò)程如下。
1)節(jié)點(diǎn)結(jié)構(gòu)定義。在構(gòu)建語(yǔ)法樹(shù)前,定義語(yǔ)法樹(shù)的節(jié)點(diǎn)結(jié)構(gòu),如圖4所示,包含節(jié)點(diǎn)類(lèi)型、節(jié)點(diǎn)值和污點(diǎn)標(biāo)記。以節(jié)點(diǎn)值作為污點(diǎn)語(yǔ)法樹(shù)的主節(jié)點(diǎn),相鄰右節(jié)點(diǎn)為污點(diǎn)標(biāo)記節(jié)點(diǎn),相鄰左節(jié)點(diǎn)表示節(jié)點(diǎn)類(lèi)型。
圖4 節(jié)點(diǎn)結(jié)構(gòu)
2)詞法分析階段。根據(jù)SQL語(yǔ)言特性,定義分隔符將SQL語(yǔ)句數(shù)組化,針對(duì)轉(zhuǎn)義符和其他特殊字符對(duì)分隔后的數(shù)組進(jìn)行合并或分割處理。根據(jù)觀測(cè)點(diǎn)的首尾標(biāo)記,對(duì)標(biāo)記之間的元素設(shè)置污點(diǎn)標(biāo)記值為1。由于包含子句的元素在語(yǔ)法分析階段將被再次分詞,因此,若元素包含子句,保留其觀測(cè)點(diǎn)首尾標(biāo)記;否則去掉觀測(cè)點(diǎn)首尾標(biāo)記。
3)語(yǔ)法分析階段。檢測(cè)節(jié)點(diǎn)中的SQL保留字,以保留字作為樹(shù)枝節(jié)點(diǎn),其后節(jié)點(diǎn)作為葉節(jié)點(diǎn),并根據(jù)保留字選擇處理分支,按相應(yīng)語(yǔ)法規(guī)則基于深度優(yōu)先原則進(jìn)行解析。以SELECT處理分支為例,使用偽代碼描述算法如下。
算法1 樹(shù)枝節(jié)點(diǎn)子句語(yǔ)法分析。
輸入:node
/*樹(shù)枝節(jié)點(diǎn)*/
node_attr
/*樹(shù)枝節(jié)點(diǎn)污點(diǎn)屬性*/
tokens
/*葉節(jié)點(diǎn)*/
tokens_attr
/*葉節(jié)點(diǎn)污點(diǎn)屬性*/
輸出:sub_tree
/*污點(diǎn)子樹(shù)*/
BEGIN
初始化:令SELECT表達(dá)式expression和表達(dá)式屬性
expression_attr為空;
switch node do
case node=′SELECT′:
for i=0 to length(tokens) do
if tokens[i]=′,′ then
SELECT表達(dá)式分析(expression,expression_a ttr)
置空expression和expression_attr
else
expression=expression+tokens[i]
token_attr=token_attr||node_attr[i]
expression_attr=[node_attr[i-1],token_att r,
node _attr[i+1]]
function SELECT表達(dá)式分析:
(sub_tokens,sub_tokens_attr)=lexer(expressio n,
expression_attr)
/*再次進(jìn)行詞法分析*/
sub_tree=parser(sub_tokens,sub_tokens_attr)
/*再次進(jìn)行語(yǔ)法分析,返回子樹(shù)節(jié)點(diǎn)和污點(diǎn)屬性*/
設(shè)置sub_tree節(jié)點(diǎn)結(jié)構(gòu)
end
output sub_tree
case node=′FROM′:…
case node=′ORDER′:…
…
END
語(yǔ)法分析完成后,生成污點(diǎn)語(yǔ)法樹(shù)。例如SQL語(yǔ)句“select * from ___”,若下劃線處為外部輸入點(diǎn),該SQL語(yǔ)句本意為拼接表名,因此正常語(yǔ)句將輸入符合表名格式的單一字符串,例如,“select * from abc”;而異常語(yǔ)句的輸入則為帶攻擊或測(cè)試目的的非單一字符串,例如,“select * from abc where 1=2”,該異常語(yǔ)句通過(guò)引入“where”關(guān)鍵字與表達(dá)式,并根據(jù)與正常語(yǔ)句返回結(jié)果的異同,測(cè)試該處是否存在SQL注入。異常語(yǔ)句和正常語(yǔ)句的污點(diǎn)語(yǔ)法樹(shù)數(shù)組結(jié)構(gòu)分別如圖5~6所示。
圖5 異常語(yǔ)句污點(diǎn)語(yǔ)法樹(shù)
圖6 正常語(yǔ)句污點(diǎn)語(yǔ)法樹(shù)
SQL注入的目的是改變?cè)姓Z(yǔ)句的邏輯,以SQL保留字和運(yùn)算符替換原本只能作為數(shù)值傳入SQL語(yǔ)句的內(nèi)容,而上述改變?cè)谖埸c(diǎn)節(jié)點(diǎn)中能夠得到體現(xiàn)。本文對(duì)SQL注入行為在污點(diǎn)語(yǔ)法樹(shù)中表現(xiàn)出的特征進(jìn)行分析和提取,將特征分為污點(diǎn)子樹(shù)特征和詞法特征兩類(lèi)。
1.3.1 污點(diǎn)子樹(shù)特征
SQL注入行為,由于其目的在于數(shù)據(jù)竊取和遠(yuǎn)程命令執(zhí)行,其請(qǐng)求數(shù)據(jù)會(huì)帶有SQL保留字、函數(shù)和相應(yīng)運(yùn)算符等。上述惡意關(guān)鍵字將直接影響語(yǔ)法樹(shù)結(jié)構(gòu),并根據(jù)污點(diǎn)節(jié)點(diǎn)中的“SELECT”等關(guān)鍵字產(chǎn)生一個(gè)或多個(gè)污點(diǎn)子樹(shù)。
1)污點(diǎn)子樹(shù)的提取。
基于深度優(yōu)先(Depth-First-Search, DFS)算法[16]遍歷語(yǔ)法樹(shù),從頭節(jié)點(diǎn)開(kāi)始,搜索污點(diǎn)標(biāo)記節(jié)點(diǎn),將最先搜索到的污點(diǎn)節(jié)點(diǎn)作為污點(diǎn)子樹(shù)頭節(jié)點(diǎn),語(yǔ)法樹(shù)中的邊表示節(jié)點(diǎn)與節(jié)點(diǎn)之前的嵌套關(guān)系,當(dāng)邊同時(shí)連接兩個(gè)污點(diǎn)節(jié)點(diǎn)時(shí),將被連接節(jié)點(diǎn)加入相應(yīng)污點(diǎn)子樹(shù)。最終生成污點(diǎn)子樹(shù)集中包含了所有污點(diǎn)子樹(shù)和節(jié)點(diǎn)信息。算法描述如下。
算法2 污點(diǎn)語(yǔ)法樹(shù)遍歷。
輸入:taintTree
/*污點(diǎn)語(yǔ)法樹(shù)*/
輸出:subTaintTree
/*污點(diǎn)子樹(shù)集*/
BEGIN
初始化:存儲(chǔ)節(jié)點(diǎn)棧stack為空;污點(diǎn)子樹(shù)集subTaintTree為空;當(dāng)前節(jié)點(diǎn)Vm為空,當(dāng)前節(jié)點(diǎn)父節(jié)點(diǎn)Vn為空;
for i=0 to length(taintTree) do
stack.push(taintTree[i])
/*第一層節(jié)點(diǎn)入棧*/
end
while stack非空 do
Vm = stack.pop()
/*從棧頂取出當(dāng)前節(jié)點(diǎn)*/
if Vm[1].children非空 then
/*Vm存在子節(jié)點(diǎn)*/
Vn=Vm
/*Vm作為下一元素父節(jié)點(diǎn)*/
stack.push(Vm[1].children)
if Vm[2]=1 then
/*添加節(jié)點(diǎn)至污點(diǎn)子樹(shù)*/
switch Vn do
case subTaintTree中存在Vn
subTaintTree[Vn].add(Vm[1].key)
/*將Vm添加至其父節(jié)點(diǎn)中*/
case subTaintTree中不存在Vn or Vn=null
subTaintTree.add(Vm[1].key)
/*將Vm加入污點(diǎn)子樹(shù)集*/
end
output subTaintTree
END
2)污點(diǎn)子樹(shù)基本特征。
通過(guò)對(duì)正常樣本進(jìn)行污點(diǎn)子樹(shù)提取后發(fā)現(xiàn),正常語(yǔ)句中的污點(diǎn)節(jié)點(diǎn)通常以單節(jié)點(diǎn)子樹(shù)的形式組成污點(diǎn)子樹(shù)集。而惡意樣本中的SQL注入語(yǔ)句,在污點(diǎn)子樹(shù)集中體現(xiàn)為一個(gè)或多個(gè)包含子節(jié)點(diǎn)的污點(diǎn)子樹(shù),因此,異常語(yǔ)句的污點(diǎn)子樹(shù)集在寬度和深度上較正常語(yǔ)句有明顯的區(qū)別。所以本文選擇污點(diǎn)子樹(shù)的寬度和深度作為一組基本結(jié)構(gòu)特征。
將算法2得出的污點(diǎn)子樹(shù)集表示為:subTaintTree={T0,T1,…,Tn}。將污點(diǎn)子樹(shù)子節(jié)點(diǎn)最大層數(shù)作為其深度,并計(jì)算整個(gè)污點(diǎn)子樹(shù)集的平均深度作為結(jié)構(gòu)特征之一;將污點(diǎn)子樹(shù)中每層節(jié)點(diǎn)數(shù)的最大值作為寬度,并計(jì)算污點(diǎn)子樹(shù)集中子樹(shù)的平均寬度作為結(jié)構(gòu)特征之一:
(1)
(2)
當(dāng)污點(diǎn)子樹(shù)深度大于1時(shí),表明頭節(jié)點(diǎn)帶有關(guān)鍵字,并和其后內(nèi)容產(chǎn)生了嵌套關(guān)系,將其稱(chēng)為嵌套子樹(shù)。當(dāng)SQL語(yǔ)句中出現(xiàn)了較多外部輸入拼接點(diǎn)時(shí),如“insert”型注入,由于其產(chǎn)生注入的位置單一,此時(shí),平均深度和寬度特征的可信度被降低,因此,通過(guò)計(jì)算污點(diǎn)子樹(shù)集中的嵌套子樹(shù)所占比,同作為基本特征,以減小上述情況出現(xiàn)的誤差。
3)污點(diǎn)子樹(shù)語(yǔ)義相似度。
語(yǔ)義相似度能表示詞語(yǔ)的相似性,由于污點(diǎn)子樹(shù)頭節(jié)點(diǎn)能體現(xiàn)一個(gè)嵌套子樹(shù)的SQL語(yǔ)句類(lèi)型;而惡意關(guān)鍵字通常出現(xiàn)在頭節(jié)點(diǎn),且在SQL語(yǔ)義上與正常值的相似度較低。當(dāng)SQL語(yǔ)句中存在多個(gè)外部輸入拼接點(diǎn),或單個(gè)拼接點(diǎn)的外部輸入被分為多個(gè)子樹(shù)時(shí),由于正常請(qǐng)求中外部輸入值的數(shù)值性和賦值規(guī)范性,在生成的污點(diǎn)子樹(shù)集中,每個(gè)子樹(shù)的頭節(jié)點(diǎn)語(yǔ)義相似度較高;而異常請(qǐng)求生成的污點(diǎn)子樹(shù)集中,由于某些子樹(shù)中出現(xiàn)嵌套,其頭節(jié)點(diǎn)為各類(lèi)關(guān)鍵字,因此語(yǔ)義相似度較低?;谏鲜鰠^(qū)別,本文對(duì)污點(diǎn)子樹(shù)集中的子樹(shù)頭節(jié)點(diǎn)計(jì)算語(yǔ)義相似度作為特征。
基于信息量理論,Lin[17]提出了基于樹(shù)狀結(jié)構(gòu)中兩個(gè)節(jié)點(diǎn)所含的信息量的大小計(jì)算語(yǔ)義相似度的方法:
(3)
其中:S1、S2表示兩個(gè)子樹(shù)頭節(jié)點(diǎn),Sp表示S1、S2的最近共同父節(jié)點(diǎn),P表示該節(jié)點(diǎn)的子節(jié)點(diǎn)個(gè)數(shù)和樹(shù)中的所有節(jié)點(diǎn)個(gè)數(shù)比值。本文在計(jì)算過(guò)程中,S1為污點(diǎn)子樹(shù)集中第一個(gè)單節(jié)點(diǎn),其他子樹(shù)頭節(jié)點(diǎn)分別作為S2,與S1計(jì)算相似度,取其平均值;當(dāng)子樹(shù)集不存在單節(jié)點(diǎn)時(shí),S1為第一個(gè)子樹(shù)的頭節(jié)點(diǎn);當(dāng)子樹(shù)集只有一個(gè)污點(diǎn)子樹(shù)時(shí),將該特征設(shè)置為缺省。
1.3.2 詞法特征
為降低誤報(bào)率,本文收集了大量假陽(yáng)性樣本,樣本中的內(nèi)容為無(wú)SQL語(yǔ)義的復(fù)雜語(yǔ)句。例如“union selected 1”。傳統(tǒng)的異常檢測(cè)方法將其判定為注入行為,但實(shí)際上因關(guān)鍵字錯(cuò)誤,屬于非注入行為。經(jīng)過(guò)污點(diǎn)子樹(shù)特征提取后發(fā)現(xiàn),部分假陽(yáng)性樣本的污點(diǎn)子樹(shù)集中也出現(xiàn)了嵌套子樹(shù),單從污點(diǎn)子樹(shù)結(jié)構(gòu)特征進(jìn)行異常判定存在誤報(bào),所以本文對(duì)污點(diǎn)語(yǔ)法樹(shù)中的詞法特征進(jìn)行分析提取。
1)惡意節(jié)點(diǎn)泛化。
經(jīng)過(guò)語(yǔ)法分析,污點(diǎn)語(yǔ)法樹(shù)的節(jié)點(diǎn)中已定義了節(jié)點(diǎn)類(lèi)型,將節(jié)點(diǎn)類(lèi)型作為詞性標(biāo)注。通過(guò)詞性可得出污點(diǎn)子樹(shù)中為關(guān)鍵字、運(yùn)算符、SQL函數(shù)的節(jié)點(diǎn)。從SQL語(yǔ)法規(guī)則中提取出985個(gè)關(guān)鍵詞作為惡意節(jié)點(diǎn)內(nèi)容,如表2所示。將出現(xiàn)表中關(guān)鍵詞的節(jié)點(diǎn)作為惡意節(jié)點(diǎn)并作泛化處理。對(duì)于不在表中的特殊字符,如“(”等,保留其原始形式,將其他字符串歸一為常量。按照表2和部分特殊字符組成惡意節(jié)點(diǎn)表。
2)節(jié)點(diǎn)基本特征。
為驗(yàn)證惡意節(jié)點(diǎn)中哪些特征對(duì)區(qū)分SQL注入行為有明顯的效果,本文從實(shí)驗(yàn)數(shù)據(jù)中隨機(jī)抽選了500個(gè)正常樣本和等量惡意樣本進(jìn)行分析計(jì)算。其中正常樣本中包含部分假陽(yáng)性樣本。對(duì)惡意樣本和正常樣本中的節(jié)點(diǎn)數(shù)和惡意節(jié)點(diǎn)數(shù)進(jìn)行統(tǒng)計(jì),如圖7所示。從圖中可看出,惡意樣本中節(jié)點(diǎn)數(shù)普遍高于正常樣本,由于假陽(yáng)性樣本的加入,正常樣本中也體現(xiàn)出多節(jié)點(diǎn)的情況。而正常樣本在節(jié)點(diǎn)數(shù)增加時(shí),惡意節(jié)點(diǎn)所占比例并不會(huì)隨著增加。反而惡意樣本中惡意節(jié)點(diǎn)所占比普遍保持在0.3至0.6之間。所以本文選擇惡意節(jié)點(diǎn)所占比和節(jié)點(diǎn)總數(shù)作為基本特征。
表2 關(guān)鍵詞泛化表
圖7 節(jié)點(diǎn)基本特征比較
3)惡意節(jié)點(diǎn)組合概率。
當(dāng)出現(xiàn)單個(gè)惡意節(jié)點(diǎn)時(shí),并不能體現(xiàn)語(yǔ)句是否是SQL注入行為,例如“union selected 1”,所以本文對(duì)惡意節(jié)點(diǎn)組合出現(xiàn)概率進(jìn)行計(jì)算。對(duì)泛化后的節(jié)點(diǎn)刪除內(nèi)部常量,以父節(jié)點(diǎn)和左節(jié)點(diǎn)作為前序節(jié)點(diǎn),組合為只有關(guān)鍵詞組成的表達(dá)式。該表達(dá)式滿(mǎn)足內(nèi)部某關(guān)鍵詞狀態(tài)只與前一關(guān)鍵詞狀態(tài)有關(guān)。該表達(dá)式作為一個(gè)序列具有馬爾可夫性質(zhì)。本文采用N-Gram模型[18]建立惡意節(jié)點(diǎn)組合的概率模型。利用惡意樣本建立一步狀態(tài)轉(zhuǎn)移矩陣P,Pij表示第n位為j的前提下,第n+1位為i的概率:
Pij=P(Xn+1=i|Xn=j)
(4)
以“^”和“$”作為起始符和結(jié)束符。通過(guò)一步狀態(tài)轉(zhuǎn)移矩陣,可以得出序列Xn={^,x0,x1,…,xn,$}滿(mǎn)足上述轉(zhuǎn)移矩陣的概率Pn。Pn體現(xiàn)了一個(gè)序列中出現(xiàn)惡意節(jié)點(diǎn)組合的概率:
(5)
在訓(xùn)練過(guò)程中,直接相乘會(huì)導(dǎo)致數(shù)據(jù)下溢,因此對(duì)上述結(jié)果作對(duì)數(shù)處理;為避免概率為0導(dǎo)致樣本數(shù)據(jù)稀疏,使用回退算法(Katz Backoff)對(duì)數(shù)據(jù)進(jìn)行平滑處理。將結(jié)果作為惡意節(jié)點(diǎn)組合概率特征。
隨機(jī)森林算法能夠快速處理大量數(shù)據(jù)并實(shí)現(xiàn)高準(zhǔn)確率的分類(lèi)效果。由于本文提取的污點(diǎn)子樹(shù)語(yǔ)義相似度特征存在缺省值,而隨機(jī)森林算法對(duì)缺省值并不敏感?;谏鲜鰞?yōu)點(diǎn),本文選擇隨機(jī)森林算法建立分類(lèi)模型。過(guò)程如下:
1)從SQL注入攻擊工具中提取各類(lèi)SQL注入的攻擊載荷(payload),以其為樣本,基于N-Gram模型建立惡意節(jié)點(diǎn)組合的概率模型。
2)獲得訓(xùn)練樣本的污點(diǎn)語(yǔ)法樹(shù)后,根據(jù)惡意節(jié)點(diǎn)表,計(jì)算節(jié)點(diǎn)基本特征;將污點(diǎn)節(jié)點(diǎn)序列化,計(jì)算惡意節(jié)點(diǎn)組合概率。
3)按1.3.1節(jié)中方法提取污點(diǎn)子樹(shù),計(jì)算污點(diǎn)子樹(shù)基本特征,對(duì)于非單一元素子樹(shù)集,計(jì)算其子樹(shù)語(yǔ)義相似度。
4)數(shù)字化特征與其類(lèi)別如表3所示。利用隨機(jī)森林算法對(duì)正常樣本和惡意樣本進(jìn)行分類(lèi)訓(xùn)練,并使用十字交叉驗(yàn)證對(duì)其分類(lèi)性能進(jìn)行驗(yàn)證。將得到的隨機(jī)森林分類(lèi)模型作為異常檢測(cè)模型。
表3 基于污點(diǎn)語(yǔ)法樹(shù)提取的特征
本文采用以下步驟實(shí)現(xiàn)基于污點(diǎn)分析的SQL注入行為檢測(cè)模型:
1)本文使用PHP源碼中提供的動(dòng)態(tài)編譯擴(kuò)展的方法,將信息提取部分作為一個(gè)可裝載的so文件加載在PHP中。
2)本文參照了SQL-parser[19],對(duì)詞法分析器和語(yǔ)法分析器算法和邏輯進(jìn)行改進(jìn),實(shí)現(xiàn)污點(diǎn)標(biāo)記的語(yǔ)法分析過(guò)程,最終生成污點(diǎn)語(yǔ)法樹(shù)。
3)對(duì)于異常檢測(cè)模型,實(shí)驗(yàn)分別選取了5 000個(gè)惡意樣本和正常樣本。其中正常樣本中包含了無(wú)SQL語(yǔ)義字符串和其他類(lèi)型攻擊樣本,如跨站腳本攻擊(Cross Site Script Attack, XSS);惡意樣本中包含了從Github[20]中搜集的SQL注入攻擊載荷(payload),包括5種常見(jiàn)SQL注入攻擊語(yǔ)句:布爾型注入、報(bào)錯(cuò)型注入、聯(lián)合查詢(xún)注入、多語(yǔ)句查詢(xún)注入和時(shí)間延遲注入。此外使用SQL自動(dòng)攻擊工具,針對(duì)不同的注入點(diǎn),生成相匹配的攻擊載荷。
為驗(yàn)證方法有效性,本文在一個(gè)PHP應(yīng)用程序中預(yù)設(shè)了數(shù)據(jù)操縱語(yǔ)言(Data Manipulation Language, DML)中的四種語(yǔ)句,在每個(gè)語(yǔ)句中設(shè)置多個(gè)外部輸入點(diǎn),分別為查詢(xún)項(xiàng)、表名、賦值語(yǔ)句等常見(jiàn)注入發(fā)生點(diǎn)。測(cè)試過(guò)程中,本文在該應(yīng)用程序中每個(gè)注入點(diǎn)下模擬攻擊者行為,通過(guò)工具和手工頻繁發(fā)送SQL注入行為請(qǐng)求,并對(duì)本文模型的檢測(cè)結(jié)果進(jìn)行統(tǒng)計(jì)和準(zhǔn)確性計(jì)算。實(shí)驗(yàn)詳細(xì)測(cè)試環(huán)境:操作系統(tǒng)為L(zhǎng)inux ubuntu 4.4.0- 75-generic;內(nèi)存為2 GB;Web服務(wù)器版本為Apache 2.4.10;PHP版本為PHP 5.3.10。
為驗(yàn)證基于污點(diǎn)分析的SQL注入行為檢測(cè)模型的準(zhǔn)確性,并和現(xiàn)有SQL注入檢測(cè)技術(shù)進(jìn)行對(duì)比,本文對(duì)兩種方法和所提模型進(jìn)行對(duì)比實(shí)驗(yàn)。包括基于關(guān)鍵字的檢測(cè)方法和基于正則表達(dá)式的檢測(cè)方法。
基于關(guān)鍵字的檢測(cè)方法:根據(jù)表2建立關(guān)鍵字列表,待檢測(cè)樣本中一旦出現(xiàn)關(guān)鍵詞則判定為注入行為?;谡齽t表達(dá)式的檢測(cè)方法:使用開(kāi)源Web框架中的通用PHP防護(hù)代碼[21],其中防御SQL注入的功能由正則表達(dá)式實(shí)現(xiàn)。
本文對(duì)1.3節(jié)中提出的兩類(lèi)特征進(jìn)行了評(píng)估,分別只采用污點(diǎn)子樹(shù)結(jié)構(gòu)特征和詞法特征與本文模型進(jìn)行對(duì)比實(shí)驗(yàn)。采用混淆矩陣的評(píng)估方法評(píng)估檢測(cè)結(jié)果,評(píng)價(jià)指標(biāo)包括精確率(Precision, P)、準(zhǔn)確率(Accuracy, ACC)、召回率(Recall, R),及精確率和召回率的調(diào)和均值(F1-Measure,F1)。
通過(guò)檢測(cè)結(jié)果表4可看出,本文模型相對(duì)于基于關(guān)鍵字和正則表達(dá)式的檢測(cè)方法,準(zhǔn)確率明顯提高;只選取污點(diǎn)子樹(shù)結(jié)構(gòu)特征和詞法特征進(jìn)行檢測(cè)時(shí),準(zhǔn)確率皆低于本文模型準(zhǔn)確率。與文獻(xiàn)[6]中提出的SVM檢測(cè)算法相比,本文模型的準(zhǔn)確率提升了1.1個(gè)百分點(diǎn);并且,對(duì)于被編碼的請(qǐng)求,使用基于流量的第三方SQL注入行為檢測(cè)工具,例如網(wǎng)站安全狗[22],并未檢測(cè)出其中的SQL注入行為,但由于本文模型在代碼層截獲數(shù)據(jù),編碼后的請(qǐng)求在代碼層內(nèi)被解碼,所以能準(zhǔn)確地檢測(cè)出編碼請(qǐng)求是否是SQL注入行為。
表4 測(cè)試數(shù)據(jù)檢測(cè)結(jié)果 %
本文研究了在PHP應(yīng)用程序下檢測(cè)SQL注入行為的方法,提出了基于污點(diǎn)分析的SQL注入行為檢測(cè)模型,其中主要運(yùn)用的技術(shù)點(diǎn)為:PHP擴(kuò)展開(kāi)發(fā)、SQL語(yǔ)法分析、污點(diǎn)分析技術(shù)和隨機(jī)森林分類(lèi)算法。實(shí)驗(yàn)結(jié)果表明,本文提出的模型在PHP應(yīng)用程序中檢測(cè)SQL注入行為有著較高的準(zhǔn)確率。
由于本文通過(guò)PHP擴(kuò)展獲取信息后基于日志文件進(jìn)行提取,因此具有一定滯后性;今后的研究方向在于將污點(diǎn)標(biāo)記過(guò)程和異常檢測(cè)模型融合在PHP擴(kuò)展中,實(shí)現(xiàn)SQL注入行為的實(shí)時(shí)檢測(cè)和攔截。
References)
[1] 360安全.2016年中國(guó)網(wǎng)站安全漏洞形勢(shì)分析報(bào)告[EB/OL].(2017- 01- 05)[2017- 06- 20]. http://bobao.#/news/detail/3905.html.(360 safe. Analysis report of Chinese Website security vulnerability in 2016 [EB/OL]. (2017- 01- 05)[2017- 06- 20]. http://bobao.#/news/detail/3905.html.)
[2] 王丹,趙文兵,丁治明.Web應(yīng)用常見(jiàn)注入式安全漏洞檢測(cè)關(guān)鍵技術(shù)綜述[J].北京工業(yè)大學(xué)學(xué)報(bào),2016,42(12):1822-1832.(WANG D, ZHAO W B, DING Z M. Review of detection for injection vulnerability of Web applications [J]. Journal of Beijing University of Technology, 2016, 42(12): 1822-1832.)
[3] youyou0635.2016年度Web漏洞統(tǒng)計(jì)之Exploit-db[EB/OL].(2017- 01- 23)[2017- 06- 20].http://www.freebuf.com/vuls/125382.html.(youyou0635. Web vulnerability statistics from Exploit-db in 2016 [EB/OL]. (2017- 01- 23)[2017- 06- 20]. http://www.freebuf.com/vuls/125382.html.)
[4] KAR D, PANIGRAHI S, SUNDARARAJAN S. SQLiDDS: SQL injection detection using query transformation and document similarity [C]// Proceedings of the 2015 International Conference on Distributed Computing and Internet Technology. Berlin: Springer, 2015: 377-390.
[5] 趙宇飛,熊剛,賀龍濤,等.面向網(wǎng)絡(luò)環(huán)境的SQL注入行為檢測(cè)方法[J].通信學(xué)報(bào),2016,37(2):88-97.(ZHAO Y F, XIONG G, HE L T, et al. Approach to detection SQL injection behaviors in network environment [J]. Journal on Communications, 2016, 37(2): 88-97.)
[6] PRIYAA B D, DEVI M I. Fragmented query parse tree based SQL injection detection system for Web applications [C]// Proceedings of the 2016 International Conference on Computing Technologies and Intelligent Data Engineering. Piscataway, NJ: IEEE, 2016: 1-5.
[7] 范春榮.基于Web日志的入侵檢測(cè)系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)[D].石家莊:河北科技大學(xué),2011:4-36.(FAN C R. Design and implementation of the Web log-based intrusion detection system [D]. Shijiazhuang: Hebei University of Science and Technology, 2011: 4-36.)
[8] NGUYEN-TUONG A, GUARNIERI S, GREENE D, et al. Automatically hardening Web applications using precise tainting [C]// SEC 2005: IFIP International Information Security Conference on Security and Privacy in the Age of Ubiquitous Computing. Berlin: Springer, 2005: 295-307.
[9] 王溢,李舟軍,郭濤.防御代碼注入式攻擊的字面值污染方法[J].計(jì)算機(jī)研究與發(fā)展,2012,49(11):2414-2423.(WANG Y, LI Z J, GUO T. Literal tainting method for preventing code injection attack in Web application [J]. Journal of Computer Research and Development, 2012, 49(11): 2414-2423.)
[10] GOLEMON S. Extending and Embedding PHP [M]. Indianapolis, Indiana: SAMS Publishing, 2006: 269.
[11] WANG Y, WANG D, ZHAO W, et al. Detecting SQL vulnerability attack based on the dynamic and static analysis technology [C]// Proceedings of the 2015 IEEE Computer Software & Applications Conference. Piscataway, NJ: IEEE, 2015: 604-607.
[12] 陸開(kāi)奎.基于動(dòng)態(tài)污點(diǎn)分析的漏洞攻擊檢測(cè)技術(shù)研究與實(shí)現(xiàn)[D].成都:電子科技大學(xué),2013:28-35.(LU K K. The research and realization of dynamic taint analysis based security attack detection technology [D]. Chengdu: University of Electronic Science and Technology of China, 2013: 28-35.)
[13] BREIMAN L. Random forest [J]. Machine Learning, 2001, 45(1): 5-32.
[14] The PHP Group. Zend Engine 2 opcode [EB/OL]. (2017- 05- 25)[2017- 08- 26]. http://php.net/manual/zh/internals2.opcodes.php.
[15] 吳江.SQL語(yǔ)言預(yù)編譯器的構(gòu)架——基于Linux操作系統(tǒng)[D].北京:北京化工大學(xué),2002:15-37.(WU J. The construction of complier for SQL-basing on Linux operating system [D]. Beijing: Beijing University of Chemical Technology, 2002: 15-37.)
[16] 張炘,廖頻,郭波.一種挖掘頻繁閉項(xiàng)集的深度優(yōu)先算法[J].計(jì)算機(jī)應(yīng)用,2010,30(3):806-809.(ZHANG X, LIAO P, GUO B. Depth-first search algorithm for mining frequent closed itemsets [J]. Journal of Computer Applications, 2010, 30(3): 806-809.)
[17] LIN D. An information-theoretic definition of similarity [C]// ICML’98: Proceedings of the Fifteenth International Conference on Machine Learning. Madison: Morgan Kaufmann, 1998: 296-304.
[18] ABOU-ASSALEH T, CERCONE N, KEELJ V, et al. N-gram-based detection of new malicious code [C]// Proceedings of the 28th Annual International Computer Software & Applications Conference-Workshops & Fast Abstracts. Washington, DC: IEEE Computer Society, 2004, 2: 41-42.
[19] SWANHART J. greenlion/PHP-SQL-parser [EB/OL]. (2016- 08- 01)[2017- 06- 20]. https://github.com/greenlion/PHP-SQL-Parser.
[20] TRIET P T M. SQL-injection-payloads [EB/OL]. (2017- 08- 20)[2017- 08- 26]. https://github.com/trietptm/SQL-Injection-Payloads/blob/master/LINKS.md.
[21] 360. 360_safe3.php [EB/OL]. (2017- 05- 29) [2017- 08- 26]. https://github.com/luislv/easycms/blob/master/lib/plugins/filecheck/tool/360_safe3.php.
[22] safedog. safedog [EB/OL]. (2017- 04- 26)[2017- 08- 26]. http://www.safedog.cn/website_safedog.html.
ZHOUYing, born in 1993, M. S. candidate. Her research interests include Web security, network attack and defense.
FANGYong, born in 1966, Ph. D., professor. His research interests include information security, network information confrontation.
HUANGCheng, born in 1987, Ph. D. His research interests include information security, network attack and defense.
LIULiang, born in 1982, Ph. D., lecturer. His research interests include network system and information security.