張冰琦 孫 偉
1(中山大學軟件學院 廣州 510006)2(中山大學信息科學與技術學院 廣州 510006)3(信息技術教育部重點實驗室(中山大學) 廣州 510006)(sunwei@mail.sysu.edu.cn)
?
一種基于污染源追蹤的PHP源代碼SQL注入漏洞檢測算法
張冰琦1,3孫 偉2,3
1(中山大學軟件學院 廣州 510006)2(中山大學信息科學與技術學院 廣州 510006)3(信息技術教育部重點實驗室(中山大學) 廣州 510006)(sunwei@mail.sysu.edu.cn)
SQL注入攻擊被列為OWASP(open Web application security project)2010年和2013年十大Web應用系統安全威脅之首.SQL注入攻擊檢測及如何提高Web代碼對SQL注入攻擊的防御能力是目前常見的研究問題之一,結合詞法分析及PHP語言特性,提出基于規則及特征匹配的漏洞檢測架構,實現了PHP源代碼的靜態檢測算法.測試結果表明該算法效果較好,具有較低的誤報率,能夠在詞法分析階段進行一定的別名分析及污染分析,從而在程序實現初期提高代碼的安全性;同時漏洞檢測框架可以進行拓展,實現對其他“taint-style”類型的漏洞檢測.
SQL注入;詞法分析;靜態分析;污染分析;規則匹配
SQL注入攻擊(SQL injection attack, SQLIA)通過在原始查詢語句中注入新的SQL關鍵字或操作從而改變原先SQL查詢語句的執行結果,常見于Web應用.此類攻擊與跨站腳本攻擊(cross-site scripting),簡稱為XSS,同為“污染類型”(taint-style)[1]的安全漏洞,產生此類攻擊的根本原因為不充分的用戶輸入驗證.針對此類型安全漏洞,如何有效地檢測及追蹤用戶未經驗證或過濾的輸入,這是解決此類問題的關鍵,因此污染源追蹤這是解決此類問題的有效方法之一.污染源追蹤有3個重要的元素,即污染源、敏感函數及凈化操作;其中污染源指代碼中接受用戶輸入的語句,例如PHP中將$_POST變量賦值給變量的操作;敏感函數指代碼中將被污染的變量送至數據庫進行相關數據庫操作的部分,例如PHP中的mysql_query函數語句;而凈化操作則指代碼中用于進行污染值凈化操作的語句,例如進行特殊字符轉義的函數mysql_escape_string等.
對于SQL注入攻擊,研究人員提出一系列檢測及防御機制,例如Livshits等人[2]使用污染分析,通過使用source,sink,derivation這3類描述符對所關注的Java源代碼漏洞進行描述,從而通過靜態代碼分析查找潛在的、符合描述的代碼漏洞,其中source描述符描述代碼中接受用戶輸入數據的語句,對應于污染源追蹤的污染源元素;sink描述符描述程序中數據不安全的使用方式,對應于污染源追蹤的敏感函數元素;derivation描述符描述數據如何在程序的對象中傳遞;Livshits等人使用指針分析(pointer analysispoints-to analysis)對代碼中的污染值傳播路徑進行分析.
Jovanovic等人[1]實現了針對PHP的漏洞檢測工具Pixy,Pixy通過使用源文本分析(literal analysis)、別名分析(alias analysis)及污染分析(taint analysis)相結合,通過在代碼中定位特定位置的污染值,之后確定污染值的傳播路徑,通過檢測敏感函數是否接受污染值從而判斷是否存在污染值與數據庫進行交互,從而實現相關漏洞的檢測.Jovanovic等人[1]使用數據流分析進行污染分析,對于數據流分析中的2個基本元素:“格”及“轉換函數”分別進行分析.Jovanovic等人[1]在漏洞檢測部分沒有考慮PHP面向對象的特性,將對象成員方法或成員變量假設為“未被污染的”,在別名分析階段,沒有考慮成員變量及成員方法與全局變量、局部變量之間的別名關系;其次,沒有考慮PHP中的數組及數組元素的別名關系,從而使得其檢測結果存在一定的誤判率.
其他相關的漏洞檢測研究成果包括AMNESIA[3]結合靜態分析及動態檢測,在靜態分析階段收集源代碼中所有的熱點(hotspot),即代碼中與數據庫進行交互的代碼語句,之后對每一個熱點可能遇到的合法SQL查詢語句進行建模,在動態檢測階段,對于動態生成的SQL查詢語句,將其與靜態分析階段的模型進行比較,當無法與模型匹配時則該SQL查詢語句可能已被注入,拒絕該SQL查詢語句在數據庫中執行;此類防御方法主要受限于其靜態分析階段所建立模型的準確性;WebSSARI[4]通過數據流分析,在程序中定位污染源,跟蹤污染值的傳遞路徑,并檢測是否有污染值被運用于特定敏感函數,從而分析如何通過使用過濾器或過濾函數保證數據庫操作的安全性,此類防御方法的局限性為默認污染值在經過特定的凈化處理之后不再具有污染屬性;Valeur等人[5]提出使用入侵檢測系統進行漏洞檢測,使用一系列典型的SQL查詢進行機器學習,為典型的查詢建模并對運行時的應用進行監控,從而辨認無法與模型相匹配的查詢,此方法的局限性為其檢測的準確性依賴于機器學習中的訓練集合的質量.
PHP語言是最為常用的腳本語言之一,SQL注入攻擊在使用PHP語言進行開發的Web應用中較為常見,因此本文提出了一種針對PHP源代碼的基于污染源追蹤的漏洞檢測算法,通過詞法分析及規則匹配對用戶的輸入進行檢測及追蹤,之后將檢測到的漏洞以報告的形式提供給開發人員,從而提高Web應用的安全性.
在PHP中最為重要的概念為別名(alias).在PHP中,2個變量可以通過使用引用操作符(&)為2個變量建立別名關系(alias-relationship),該操作符可以直接運用至賦值或與函數形式參數或實際參數相結合,進行傳引用調用(call-by-reference),引用即不同的名字可以訪問同一個變量內容.在PHP中變量名和變量內容是不一樣的,因此不同的變量可以指向同一個內容.結合本文的使用場景,污染分析無法離開別名分析,例如當變量$a接收用戶輸入的數據,當變量$b通過引用操作符與變量$a互為別名關系時:$b=&$a,則此時變量$a與$b皆是被污染的;若沒有進行別名分析則會產生漏判.
已有的別名分析工作包括Anderson[6],Steensgaard[7]及Lam[8]等人的方法,其中大部分方法皆是針對C語言或者Java語言等編寫的,因此大部分分析方法無法通過轉換直接運用于PHP,原因包括:1)C語言和Java語言中的指針與PHP中的引用為完全不同的概念.C語言中的指針指保存內存地址的特殊變量;而PHP的引用則是符號表別名,而不直接存儲內存地址,即PHP變量之間的別名關系是通過符號表的等價關系來表示的,而不是通過是否存儲相同的內存地址來識別2個變量是否互為別名關系.2)PHP是動態決定類型,意味著PHP代碼中變量的類型將不會在程序源碼中明確聲明,具體的類型是在執行時動態決定的,并且可以在程序執行過程中被改變;在PHP中,所有變量Zend默認為引用,甚至是僅僅包含標量值(scalar value)的變量也默認為使用引用實現;在參數傳遞方面,PHP語言的引用與C語言的指針也有所不同,在C語言中,當2個變量指向相同的內存地址,在源碼中無論何時一個變量的值發生變化,另一個變量由于指向相同的內存地址,即其所指向的內存地址中的值發生變化時,則該變量的值也同時發生變化;在PHP中,引用的值是可以變化的,對于源碼:
$x1=1;
$x2=2;
a($x1);
function a(& $p){
$p=&$GLOBALS[‘x2’];
}
由于$x1與$p只是符號表的別名關系,因此在函數a中對$p進行更改,只有$p的值發生變化時才會指向全局變量$x2指向的內容,$x1的值將不會被更改;Nenad指出此類問題在其寫論文時尚未被解決,只有Liu等人提到對Python程序使用指針分析算法進行分析.本文所實現的檢測工具將會使用“域”的概念解決此類別名問題,即默認函數的形參屬于該函數的局部變量,在上述例子中,由于變量$p屬于函數a的局部變量,而變量$x1屬于全局變量,因此當$p值發生變化時,僅會對與其處于相同作用域的、且具有別名關系的變量產生影響,全局變量$x1值并不會發生變化.
過程內(Intraprocedural)的別名分析較為簡單,對于過程間(Interprocedural)的別名分析有一個難點:即如何處理遞歸函數調用.由于每一個被調用的遞歸函數都包含其自身的一份局部變量拷貝(variable incarnations),即對于每一個遞歸函數內部的每一個局部變量,該函數每被調用一次就會產生關于特定調用的該變量的一份拷貝;在大多數情況下,從代碼靜態分析的角度無法直接決定一個遞歸函數的遞歸調用鏈的深度,因為其調用鏈的深度取決于一些動態的屬性,例如取決于數據庫返回的數據或用戶的相關輸入;因此靜態分析需要面臨“無限”個數的變量“化身”,結合污染分析,該特性意味著污染分析底層所用的“格”將會無限增加高度,即污染分析將不會終止,因此Jovanovic等人[1]提出一個原則作為別名分析的基礎原則:在函數體內,別名分析只追蹤關于全局變量及其自身的局部變量的化身.即在全局域內只考慮全局變量,該原則使得分析過程中只會產生有限數量的變量,本文在過程間的別名分析中采納Jovanovic等人提出的該原則,在函數內部進行別名分析及污染源追蹤時,僅考慮全局變量及該函數自身的局部變量,以此簡化問題.
對于過程間分析,由于考慮函數調用,有上下文相關的過程間分析及上下文無關的過程間分析2種:上下文相關的過程間分析能夠區分同一函數的不同調用;而上下文無關的過程間分析僅能夠區分不同函數的調用,不能區分同一函數的不同調用;2種分析結果相比較,上下文相關的過程間分析具有較高的精確度.本文實現的靜態代碼檢測工具是通過記錄相應函數調用的具體位置以區分同一函數的不同調用,實現上下文相關的過程間分析,從而使污染分析更為可靠.
PHP中“域”的概念對于變量值的追蹤十分重要.PHP從“域”的角度來看有2種類型的變量:局部變量,即出現在函數的局部域中的變量;以及全局變量,即出現在全局域內的變量,在PHP中等價于在函數作用域外的變量;函數的形參屬于局部變量一類.在函數內,全局變量的訪問有2種方式:第一種方式為通過關鍵字“global”,使用該關鍵字相當于聲明局部變量$a與全局變量$a互為別名關系;第二種方式為使用特殊的$GLOBALS數組,該數組在程序的任意處皆可見;通過使用$GLOBALS數組,全局變量甚至可以在函數內被重新引用到新值,使用關鍵字“global”則沒有這樣的功能.本文僅提供對“global”關鍵字的支持,暫不提供對$GLOBALS數組的支持.在進行過程間別名分析時“域”的概念十分重要,對于全局變量之間的別名問題、被調用函數的形參之間的別名問題、全局變量與被調用函數的形參之間的別名問題、全局變量及調用者的局部變量之間的別名問題都需要進行單獨的分析,從而為別名分析之后的污染分析建立基礎,降低漏判率及誤判率.本文通過對變量的“域”屬性進行區分,對此4類別名問題進行分析,從而在此別名分析基礎上進行以下污染分析:
1) 對于全局變量之間的別名問題,由于全局變量的作用域均為全局,因此污染值可以在全局變量之間進行傳遞,對于全局變量$a及$b,若$b被污染,且$a=&$b,則$a亦成為被污染的,變量$a與$b互為別名關系;全局變量之間的別名關系將會被完整地傳遞到被調用的函數中;
2) 對于被調用函數的形參之間的別名問題,此類情況只有當函數的形參之間存在別名關系時發生,例如對于函數b的2個形參$bp1及$bp2,兩者都是通過引用傳遞,對于變量$b1,$b2,當$b1=&$b2成立時,若使用語句b($b1,$b2)進行函數b的調用,由于$b1與$b2互為別名關系,則形參$bp1與$bp2也互為別名關系;此時若變量$b2是被污染的,則$b1也是被污染的,在此處被調用的函數b中,形參$bp1與$bp2同樣為被污染的;本文實現的檢測工具暫不提供此類別名關系的檢測;
3) 全局變量與被調用函數的形參之間的別名問題,由于全局變量的別名關系及污染值將會被完整地傳入被調用參數,且當函數的形參與實參具有引用賦值關系時,則相應的形參與實參之間具有別名關系;則對于全局變量$a1,當$a1為被污染時,則此時若使用$a1作為實參進行函數調用,且相應形參為引用賦值,由于兩者具有別名關系,則函數對應的形參也為被污染的,此時在函數域內,與形參互為別名關系的變量同樣為被污染的;
4) 全局變量及調用者的局部變量之間的別名問題,由于調用者的局部變量之間的別名關系無法被被調用者所改變,但是被調用函數有可能改變調用者的局部變量或全局變量的引用值;則被改變的變量將會根據新值是否為被污染而進行處理;例如$GLOBALS數組的使用,由于該數組內元素在程序任意處可見,且可以被重新引用賦值,若所賦的新值為被污染的,則該變量值為被污染的,此時若調用者的局部變量與該全局變量有別名關系,則其局部變量將成為被污染的.本文暫不考慮此類情況.
2.1 模式匹配
模式匹配為提供一系列匹配條件規則,對于給定的一個字符串,在其內容中尋找可以匹配的模式,當一個匹配確定之后,執行該匹配模式對應的相關操作.相應的原理描述如下:已知長度為n的文本字符串:S=S1S2S3…Sn和一長度為m(m≤n)的模式字符串:T=T1T2T3…Tm,之后在字符串S中搜索是否存在長度為m的子串:Si-1Si-2Si-3…Si-m,使得Si-j=Tj,j=1,2,3,…,m,i≤n-m;將模式T和文本S從左至右逐個搜索,若在某一位匹配失敗,則將模式T向右移動1位,仍從模式T的第1位重新開始搜索.
例如在詞法分析程序生成器Flex中,一系列匹配模式是通過正則表達式定義,當Flex生成的掃描程序(Scanner)運行時,它將對其輸入內容進行分析,從而找到符合某一個匹配模式的字符串;若同時符合多個匹配模式則采取貪婪算法匹配最長的那個模式;若2個模式匹配的長度相同,則匹配在Lex中最新定義的那個模式;當確定所匹配的模式時,掃描程序將會記錄被匹配的單詞(Token)的長度,并使該單詞對于全局可見(使用一個全局指針指向該單詞);之后繼續對剩余的文本進行模式匹配;若當前沒有一個規則匹配,則執行默認的規則:即默認下一個字符是匹配的,并輸出至標準輸出.對于每一個模式規則都可以有一個對應的操作,當相應規則匹配之后將會執行該操作;若該操作為空則規則匹配之后不會進行任何操作.
本文在規則庫中通過對源代碼詞法分析之后生成的單詞(Token)設計相應匹配規則,從而對源代碼進行污染分析;之后在知識庫中對匹配的規則進行收集及整理,對于每一個所匹配規則對應的代碼漏洞類型設計相應的代碼修補建議,之后以報告的形式反饋至開發人員.
本文所實現的靜態代碼檢測工具通過使用詞法分析得到的單詞序列(Token)構造所需的過濾規則,通過制定過濾規則并進行模式匹配實現PHP源代碼的別名分析及污染分析,即使用規則庫進行污染源、敏感函數、凈化操作的檢測,并進行污染值傳播路徑的追蹤.過濾規則所檢測的操作包含簡單賦值、一元賦值、二元賦值及引用賦值,并考慮PHP面向對象的特性,對公有成員變量的賦值操作進行污染值追蹤;暫不考慮面向對象的成員方法與全局變量、局部變量之間的別名關系;對于PHP的數組,本文實現的靜態檢測算法將考慮數組間的別名關系及其污染值傳遞,暫不考慮數組元素之間的別名關系及其污染值傳遞,例如當一個存有污染值的數組通過引用賦值給另一個數組時,本文提出的檢測算法可以檢測到該別名關系并對該污染值進行追蹤;當一個存有污染值的數組元素被引用賦值給另一個變量或數組元素,本文提供的算法暫時無法檢測到該別名關系及相關污染值的傳播,由于以上原因,使得本文的靜態代碼檢測算法存在一定的誤判率.
3.1 算法架構
本文所實現的靜態代碼檢測工具主要基于一個開放及可拓展的架構,利用詞法分析、別名分析及規則匹配進行污染源的檢測及其傳播路徑的追蹤,最終在分析結束后給相關人員輸出漏洞缺陷報告,其架構如圖1所示.

圖1 靜態檢測算法架構圖
架構主要由輸入、處理引擎和輸出3部分組成,其功能特點如下:
1) 輸入.由代碼和規則庫組成,規則庫將根據輸出的知識庫和漏洞缺陷警告等信息進行改進.
2) 處理引擎.由代碼預處理、漏洞過濾、警告生成、知識生成等各個功能組件構成,具有良好的擴展性和穩定性;本文實現的漏洞檢測工具重點實現了代碼預處理、漏洞過濾、警告生成3個功能組件.
3) 輸出.由知識庫和漏洞缺陷警告組成;知識庫的意義是生成有價值的知識,指導開發人員提高編程質量,同時也對規則庫的完整性和準確性提供支持.本文漏洞檢測工具實現了漏洞缺陷警告功能,知識庫的提出為下一步研究提供了接口和思路.
3.2 相關定義
在本文提出的漏洞檢測算法中,其中V表示PHP代碼中存在的變量集合;T表示PHP代碼詞法分析之后得到的Token集合;F表示PHP代碼中可能存在的變量的屬性或變量的字段集合;使用S表示變量或屬性所屬的域,域值為“global”或函數名或方法名,當域值為函數名或方法名時,則表示該變量為此函數的局部變量;使用L表示程序中函數或方法被調用的位置;N表示PHP代碼中被調用的方法名或函數名;M表示PHP代碼中用戶自定義的函數名或方法名;Z表示方法或函數所使用的參數.之后定義以下8種關系:
vR(variable:V,tokenT,scopeS)
vRF(variable:V,field:F,tokenT,scopeS)
LE(invocation location:L,method:M,scopeS)
Store(base:V,field:F,source:V,scopeS)
load(base:V,field:F,dest:V,scopeS)
assign(dest:V,sourceV,scopeS)
actual(invocation location:L,parameter:Z,variable:V,scopeS)
formal(method:M,parameter:Z,variable:V,scopeS)
在上述8種關系中,variable表示變量集合;token表示變量對應的Token集合;scope表示域值.域值可分為2種,即全局或函數局部變量,當為全局變量時,域值為“global”;當為函數局部變量時,域值為對應函數名或方法名,域值對于之后的污染傳播路徑追蹤較為重要,默認store,load及assign關系均為當變量處于相同域時才可識別.
vR作為8種關系的基本關系,vR(v,t,s)表示域值為s的變量v在詞法分析之后對應于Tokent;vRF(v,f,t,s)表示域值為s的變量v的字段f在代碼詞法分析之后對應于Tokent;store表示變量值存儲至變量的字段中,store(v1,f,v2,s)對應的代碼語句為:v1.f=v2,且2個變量的域值皆為s;load表示在變量的字段中加載另一個變量的值,且2個變量的域值皆為s,load(v1,f,v2,s)對應的代碼語句為:v2=v1.f;assign表示變量之間的賦值,assign(v1,v2,s)所對應的代碼語句為:v1=v2,除了一般的賦值關系,assign也包括引用賦值類型的檢測,由于引用賦值仍然屬于賦值的一種,因此與其他類型賦值關系統一用一種關系表示;LE(l,m,s)表示方法m在l處被調用,且該方法所屬域為s;actual(l,z,v,s)表示變量v在調用位置l被作為參數z的實參進行傳遞,且實參v所屬作用域為s;formal(m,z,v,s)表示函數或方法m的參數z用變量v表示,即v為形參,所屬作用域為s;注意函數的形參將作為函數的局部變量,即其域值為對應的方法名;之后定義8種規則進行模式匹配:
R1:vR(v,t,s)
R2:vRF(v,f,t,s)
R3:vR(v1,t,s):assign(v1,v2,s),vR(v2,t,s)
R4:vRF(v1,f,t,s):store(v1,f,v2,s),vR(v2,t,s)
R5:vRF(f,v1,t,s):load(v2,f,v3,s),store(v1,f,v3,s),vRF(v2,f,t,s)
R6:vRR(v1,s1,v2,s2)
R7:LE(l,m,s)
R8:vM(v1,m,v2):LE(l,m),formal(m,z,v1,s1),actual(l,z,v2,s2)
其中R1及R2兩個規則分別用于檢測變量、變量的字段與詞法分析之后的Token的對應關系,此規則用于檢測用戶輸入數據的存儲,例如當PHP代碼從PHP代碼的超全局變量$_POST獲取數據時,即可通過該規則檢測到相應的代碼;R3規則由2個關系組成:assign(v1,v2,s)及vR(v2,t,s),表示由于v2在代碼詞法分析之后與Tokent相對應,而代碼中出現了v1=v2的語句,因此v1在賦值語句之后也與Tokent對象相對應,在實際中,若變量v2存儲了用戶輸入的數據,則賦值語句之后,變量v1存儲的數據也是用戶輸入的數據,從而發現用戶輸入數據的值傳遞;R4規則vRF(v1,f,t,s)及R5規則vRF(f,v1,t,s)表示域值為s的變量v1的字段f對應于Tokent,2個規則結論相同但值傳遞路徑不相同,路徑傳遞解釋帶入相應關系即可;規則R6表示s1作用域的變量v1與s2作用域的變量v2有別名關系,即v1=&v2,當s2作用域的v2變量值為污染值時,s1作用域的v1變量值同樣為污染的;R7表示方法或函數m在l處被調用,調用時所在作用域為s,該規則主要用于檢測被調用的函數或方法;R8規則vM(v1,m,v2)表示函數或方法m的形參為v1,實參為v2,兩者存在別名關系,其中s1為形參所屬的作用域,s2為實參所屬的作用域;需要對實參進行污染檢測從而判斷形參是否已被污染;當實參被污染時,形參及函數作用域中與形參具有別名關系的變量均為被污染的.
3.3 算法實現
本文實現的SQL注入漏洞檢測算法主要分為2部分:一部分為別名分析,另一部分為污染分析,總體算法流程如下:
1) 遍歷存儲的Token集合,獲取所關注的Token類型,例如T_VARIABLE,T_STRING,T_FUNCTION及T_BITWISE_AND等,為關注的Token類型設置監聽器;
2) 當監聽器獲取到其所監聽的Token類型時,進行以下處理,對于所有關注的Token類型對應的監聽器:
① 通過規則庫獲取指定規則庫或使用默認規則庫通過關鍵字查詢,獲取當前Token相關的過濾規則;
② 通過規則匹配進行漏洞過濾,當出現當前Token所匹配的規則時,記錄當前Token的相關信息.
3) 將所有滿足過濾規則的漏洞信息進行格式化,生成漏洞報告輸出,并同時處理知識生成存儲至知識庫.
算法中Token對象將會以關聯數組形式儲存Token對象的相關信息,包括Token對象對應的代碼行號、列號、Token對象的內容、Token類型的名稱等,存儲此類信息主要是為了進行漏洞代碼定位時能夠為開發者提供充足的信息,以便漏洞修補.
在上述總體算法流程基礎上,對于別名分析,本文實現的檢測工具提供以下3種情況下的別名關系檢測:1)變量之間的別名關系,包括全局變量之間及局部變量之間的別名關系;2)函數形參與全局變量之間的別名關系;3)數組之間的別名關系.在以上3種別名關系的基礎上進行污染分析.
對于污染分析,本文實現的檢測工具提供對5種操作類型的檢測:簡單賦值、一元賦值、二元賦值、引用賦值及公有成員變量的賦值操作,其中簡單賦值為通過“=”等號為變量進行賦值,一元賦值操作符op在PHP源代碼中形如“$a=op $b”,其中一元操作符不包括“&”操作符;一元操作符作用于變量之后,變量$a是否被污染將取決于變量$b是否為污染值以及一元操作符的具體類型,例如對于加號“+”、減號“-”等,當其作用于被污染的字符串類型變量$b時,$a的值將會成為數值類型的值,因此污染值被“凈化”;而對于強類型轉換“(string)”操作符,由于不知道變量$b是否被污染,因此無法判斷$a變量的值是否被污染,因此賦值后的變量$a是否被污染取決于變量$b是否被污染,若$b被污染,則$a同樣被污染;相關一元操作符及其作用后變量$a的污染值情況如表1所示:

Table 1 Taint Analysis of the Unary Operators
二元操作符的分析與一元操作符類似,二元操作符包括算術運算操作符、字符串連接操作符、邏輯操作符、比較操作符、位移操作符及按位邏輯操作符,其中字符串連接操作符及按位邏輯操作符,當2個源操作變量其中之一包含污染值時,則目的操作變量為“被污染的”,其余二元操作符均有“凈化”作用,相關二元操作符及其作用后目的操作變量的污染值情況如表2所示:

Table 2 Taint Analysis of the Binary Operators
表1及表2皆參考了文獻[1]及文獻[8]的相關內容;對于引用賦值符號“&”,對應的Token類型為“T_BITWISE_AND”,本文實現的引用賦值類型檢測包括2種情況:變量之間的引用賦值以及函數形參與實參之間的引用賦值;對于面向對象的公有成員變量的賦值操作,通過對“→”符號(T_OBJECT_OPERATOR)的監聽來進行賦值操作的識別及污染值的追蹤.
本文通過選擇了DCP Portal 6.1.1中的68個PHP文件及本科生課程設計的個人博客項目wmblog的12個PHP文件進行別名分析及污染分析,實驗結果如表3所示:

Table 3 Test Results
以上實驗結果是通過本文實現的代碼檢測工具對目標文件進行檢測,之后通過人工檢查PHP源代碼判斷是否誤判.由以上實驗結果可以看出,誤判率為8.16%,是否誤判主要依據為是否對過濾規則正確地進行模式匹配;由于本文所定義的規則有限,因此存在尚未定義過濾規則的污染值傳遞情況,例如類成員方法內的污染值傳遞及數組元素間的污染值傳遞情況,對此類污染值傳遞過程暫不進行考慮,因此本文實現的漏洞檢測工具具有一定的漏判率.
4.1 類的公有成員變量的污染值檢測
對圖2所示的特定代碼段進行檢測,漏洞報告內容如圖3所示;由漏洞檢測報告可知,該代碼段中接收用戶輸入的變量被成功檢測,并成功對其污染路徑進行追蹤,本示例證明本文實現的靜態代碼檢測算法能夠對PHP面向對象的特性提供一定的支持,能夠成功對類的公有成員變量進行污染值傳播路徑的追蹤.

圖2 PHP源代碼段示例

圖3 PHP源代碼檢測結果示例

圖4 PHP源代碼示例
4.2 全局變量及局部變量的污染值檢測
對圖4所示的代碼段進行檢測,漏洞檢測結果如圖5所示.由漏洞檢測報告可知,對于全局變量及函數作用域內的局部變量,本文實現的代碼檢測工具能夠正確進行別名分析,并在污染值追蹤過程中能夠正確區分不同作用域的變量,從而保證全局變量及局部變量相同變量名時污染分析能夠正常進行.

圖5 PHP源代碼檢測結果示例
4.3 函數調用的污染值檢測
對圖6所示的代碼段進行檢測,漏洞檢測結果如圖7所示.由檢測結果可得,本文實現的代碼檢測工具能夠對自定義函數的形參及實參進行正確的別名分析,并能夠對不同作用域的變量進行正確的別名分析及污染值追蹤.

圖6 PHP源代碼示例

圖7 PHP源代碼檢測結果示例
本文針對常見的SQL注入攻擊及防御方法進行總結,并對PHP語言特性進行分析,之后提出了基于規則匹配的PHP源代碼SQL注入檢測算法,該算法利用PHP詞法分析之后產生的Token序列,結合PHP語言特性,對用戶輸入制定一系列的過濾規則,對用戶未經過濾或凈化操作的輸入進行檢測及追蹤,生成漏洞缺陷報告,并生成相應知識進行知識庫的構建.本文提出的檢測算法經實驗證明,具有較低的誤報率,但由于該算法基于詞法分析,在此階段進行別名分析及污染值的追蹤將會受到詞法分析特性的限制,且定義的過濾規則有限,因此算法具有一定的漏報率.在未來的研究中,將會進一步完善規則庫和知識庫的搭建,并通過結合語法分析階段的污染檢測算法從而降低誤報率及漏報率,并進一步提供對其余“污染類型”的Web漏洞檢測功能.
[1]Jovanovic N, Kruegel C, Kirda E. Static analysis for detecting taint-style vulnerabilities in web applications[J]. Journal of Computer Security, 2010, 18(5): 861-907
[2]Livshits V B, Lam M S. Finding security errors in Java programs with static analysis[C] //Proc of the 14th USENIX Security Symp. Berkeley: USENIX Association, 2005: 18-18
[3]William G, Halfond J. Alessandro Orso. AMNESIA: Analysis and monitoring for neutralizing SQL-injection attacks[C] //Proc of the 20th IEEE/ACM Int Conf on Automated Software Engineering. New York: ACM, 2005: 174-183
[4]Huang Y, Yu F, Hang C, et al. Securing Web application code by static analysis and runtime protection[C] //Proc of the 13th Int Conf on World Wide Web (WWW’04). New York: ACM, 2004: 40-52
[5]Valeur F, Mutz D, Vigna G. A learning-based approach to the detection of SQL attacks[C] //Proc of the Conf on Detection of Intrusions and Malware and Vulnerability Assessment (DIMVA). Berlin: Springer, 2005: 123-140
[6]Steensgaard B. Points-to analysis in almost linear time[C] //Proc of the 23rd ACM SIGPLAN-SIGACT Symp on Principles of Programming Languages (POPL’96). New York: ACM, 1996: 32-41
[7]Wilson R P, Lam M S. Efficient context-sensitive pointer analysis for C programs[D]. Stanford: Stanford University, 1998
[8]謝億鑫, 孫樂昌, 劉京菊. 基于數據流分析的SQL注入漏洞發現技術研究[J]. 微計算機信息, 2010, 26(5-3): 163-165

張冰琦
碩士研究生,主要研究方向為信息安全.
icy397@hotmail.com

孫 偉
教授,博士生導師,主要研究方向為網絡安全和多媒體技術通信.
sunwei@mail.sysu.edu.cn
A PHP Source-Code SQL Injection Attack Detection Algorithm Based on Taint Tracking
Zhang Bingqi1,3and Sun Wei2,3
1(SchoolofSoftware,SunYet-senUniversity,Guangzhou510006)2(SchoolofInformationScienceandTechnology,SunYet-senUniversity,Guangzhou510006)3(KeyLaboratoryofInformationTechnology,MinistryofEducation(SunYet-senUniversity),Guangzhou510006)
The concept of “SQL injection” has been proposed for more than 10 years, however, SQL injection attack was still rated the number one attack on the Open Web Application Security Project(OWASP) in 2013. With the rapid development of dynamic Web applications, PHP becomes popular because it's fast, reliable and can be combined with many different types of RDBMS, and it's also a cheap option for developing and hosting applications on the Web. PHP is a powerful language which can access files, execute commands and open network connections on the server. However, these properties also make anything is run on a Web server insecure by default. As there are several ways of utilizing PHP, there are many configuration options controlling its behavior. A large selection of options guarantees that PHP can be utilized to a lot of purposes. With proper runtime configuration options and coding practices, PHP can provide exactly the combination of freedom and security. This paper considers the security risks related to PHP programming language, and describes different situations which will lead to website vulnerabilities. It also proposes a static lexical analysis framework for detecting SQL injections based on the matching rules, and implements the PHP source-code SQL injection attack detection algorithm. The experiments demonstrate that the algorithm is effective, and it can also be extended to detect other “taint-style” Web vulnerabilities.
SQL injection; lexical analysis; static analysis; taint analysis; matching rules
2015-10-06
廣東省自然科學基金項目(S2013010013728);澳門科技發展基金項目(097/2013/A3)
TP393.08