趙勇濤
(湖北第二師范學(xué)院 湖北 武漢 430205)
PHP語言憑借易于訪問、功能豐富、代碼運(yùn)行效率高等優(yōu)點(diǎn)成為開發(fā)Web應(yīng)用程序系統(tǒng)的最受歡迎的語言之一。PHP的廣泛使用也導(dǎo)致對Web應(yīng)用中PHP安全漏洞的攻擊逐漸增多,這些漏洞對Web應(yīng)用程序構(gòu)成了嚴(yán)重的安全威脅。因此,在發(fā)布Web應(yīng)用之前,應(yīng)檢查Web應(yīng)用的源代碼,確保在攻擊者發(fā)現(xiàn)Web應(yīng)用上的安全漏洞之前盡快完善安全防護(hù),提高Web應(yīng)用對安全風(fēng)險的能力,有效抵制針對Web應(yīng)用的非法入侵。
靜態(tài)代碼分析是指在不啟動程序的情況下分析程序的源代碼,并根據(jù)可配置的安全規(guī)則檢測代碼中的缺陷。根據(jù)不同的實(shí)現(xiàn)原理,靜態(tài)代碼分析可以分為兩類。一種是分析源代碼編譯后分析中間文件,如字節(jié)碼;另一種是分析源文件。分析字節(jié)碼主要用于檢測諸如規(guī)范和代碼樣式之類的問題。源文件解析是指用靜態(tài)代碼分析工具解析、編譯、鏈接代碼,以生成中間系統(tǒng)數(shù)據(jù),如控制流圖。完成此步驟后,再使用復(fù)雜的靜態(tài)分析工具的驗證規(guī)則來匹配和跟蹤中間文件數(shù)據(jù),以查找和檢測缺陷并最終獲得檢測結(jié)果。基于源文件的常見靜態(tài)分析技術(shù),包括詞法分析、語法分析、數(shù)據(jù)流分析等[1]。
詞法分析是前端編譯的第一步,主要原理是從左到右逐個字符地掃描組成原始程序的字符串。換句話說,詞法分析就是逐字符掃描源代碼并進(jìn)行適當(dāng)?shù)姆治觯R別出一個個令牌。令牌是指具有詞法意義的最小單元,如變量、關(guān)鍵字,將源代碼分割成很多令牌組成的數(shù)組,從而形成令牌流。
2.1.1 語法分析
詞法分析的結(jié)果是一系列令牌。這些令牌彼此獨(dú)立,彼此沒有任何連接。因此,直接基于此令牌序列分析數(shù)據(jù)流非常繁瑣。語法分析可以識別這些令牌序列之間的關(guān)系,并將其表示為易于理解的中間表達(dá)形式,即抽象語法樹。解析后獲得的抽象語法樹實(shí)際上是一個數(shù)組,但是數(shù)組中的每個元素都不是標(biāo)記,而是類的一個對象。這些對象是上面定義的數(shù)據(jù)結(jié)構(gòu)對象,以簡化后續(xù)程序處理。例如,有如下代碼,見圖1。

圖1 PHP代碼片段
其抽象語法樹是一個數(shù)組,而第一個元素是PhpParserNodeExprAssign類的對象,它對應(yīng)于源代碼分配運(yùn)算符。第二個元素是PhpParserNodeStmtEcho_,它對應(yīng)于第二行代碼中的echo指令。每一行代碼恰好對應(yīng)于類對象,并且該類包含var、expr等變量、常量符號,方便在進(jìn)行數(shù)據(jù)流時根據(jù)類的名稱判斷代碼是復(fù)制語句還是輸出語句,同時,通過獲取成員變量的值可以輕松地獲取變量的名稱以及有關(guān)其分布的信息。可見分析語法樹比基于token序列的詞法分析方便得多,并且具有更高的抽象級別,更適合于編程操作[2]。
2.1.2 數(shù)據(jù)流分析
數(shù)據(jù)流分析是指用于獲取有關(guān)數(shù)據(jù)如何沿程序執(zhí)行路徑傳遞相關(guān)信息的一組技術(shù),目的是提供有關(guān)流程如何處理其數(shù)據(jù)的全局信息,實(shí)際上并沒有啟動該程序。在程序運(yùn)行時,它使用靜態(tài)代碼顯示相關(guān)信息。數(shù)據(jù)流分析是靜態(tài)代碼分析的一種常用方法,并且是根據(jù)編譯原理來優(yōu)化代碼的有效方法。數(shù)據(jù)流分析中的大多數(shù)問題與捕獲各種程序?qū)ο螅ɡ绻潭ㄖ怠⒈磉_(dá)式、常量、變量等)有關(guān)。由于靜態(tài)分析本身的局限性,數(shù)據(jù)流分析通常忽略條件判斷,即if或for語句的控制條件,這意味著默認(rèn)情況下所有路徑都是可訪問的,目的是減少檢測遺漏。
數(shù)據(jù)流分析方法通常分為兩種:自下而上的分析和自上而下的分析。自下而上的數(shù)據(jù)流分析意味著,如果在程序代碼分析過程中檢測到危險的函數(shù)調(diào)用,則監(jiān)視函數(shù)的參數(shù),直到確認(rèn)參數(shù)是否來自程序為止,這種分析方法要求安全審核員熟悉內(nèi)部功能和機(jī)制的使用。畢竟,一個函數(shù)可以有多個參數(shù),但是實(shí)際漏洞也許只是一個參數(shù)。自上而下的數(shù)據(jù)流分析使用用戶輸入,請求標(biāo)頭輸入,環(huán)境變量輸入等作為跟蹤的起點(diǎn),然后依次遍歷解析器邏輯,收集被其“污染”的所有變量和函數(shù),形成一個樹結(jié)構(gòu),該樹結(jié)構(gòu)顯示用戶輸入的傳播路徑。調(diào)用危險函數(shù)時,要做的就是查看參數(shù)是否在路徑樹中。如果在,則意味著產(chǎn)生漏洞。
2.2.1 Fuz技術(shù)
Fuzz技術(shù),也稱為模糊測試,近年來已成為一種流行的安全測試方法,該技術(shù)通過將大量意外數(shù)據(jù)注入目標(biāo)系統(tǒng)并監(jiān)視系統(tǒng)異常反應(yīng)來檢測軟件漏洞。該技術(shù)可以充分利用計算機(jī)的功能來隨機(jī)生成和發(fā)送測試人員預(yù)先生成的大量結(jié)構(gòu)數(shù)據(jù)。同時,還能客觀地引用測試人員的安全測試經(jīng)驗。執(zhí)行模糊測試的過程可以分為四個階段。
(1)生成大量的測試數(shù)據(jù);
(2)將生成的測試數(shù)據(jù)發(fā)送到目標(biāo)系統(tǒng);
(3)自動監(jiān)視目標(biāo)系統(tǒng)的注釋和狀態(tài),確認(rèn)是否有錯誤、故障等反饋;
(4)根據(jù)目標(biāo)系統(tǒng)的注釋確定是否存在任何潛在的安全漏洞。
在信息安全中,模糊測試通常用于自動檢測二進(jìn)制軟件中的堆棧溢出漏洞。近年來,越來越多的Web安全研究人員對模糊測試進(jìn)行了遷移應(yīng)用,用于查找Web安全漏洞。通過創(chuàng)建各種特定的攻擊有效負(fù)載集并與適當(dāng)?shù)哪:郎y試程序配合使用來對目標(biāo)Web系統(tǒng)進(jìn)行Fuzz檢測,可以有效地提高檢測效率。
2.2.2 黑盒/灰盒測試技術(shù)分析
黑盒測試是一種軟件測試方法。測試人員不需要知道有關(guān)程序的任何內(nèi)部信息,也不需要知道用于開發(fā)程序的相應(yīng)程序代碼、體系結(jié)構(gòu)和語言。只需要了解有關(guān)程序的輸入、輸出和邏輯功能的信息。用于Web應(yīng)用程序的大多數(shù)動態(tài)檢測工具都基于黑盒測試,這些工具通常以掃描儀或漏洞測試工具的形式存在。前者自動化程度更高,并且可以跨Web應(yīng)用程序執(zhí)行完整的故障檢測,如指紋識別、爬蟲程序等。對于漏洞檢測,主要利用負(fù)載測試庫檢測漏洞,自動掃描目標(biāo)Web應(yīng)用程序中包含的頁面,并測試其中的輸入點(diǎn),然后通過分析從測試數(shù)據(jù)(例如AWVS和AppScan)返回的信息,達(dá)到檢測Web應(yīng)用程序漏洞的目的。
大多數(shù)黑盒檢測工具都使用Fuzzing技術(shù)。在測試Web應(yīng)用程序時,通常會根據(jù)漏洞創(chuàng)建的原理使用手動編寫的測試數(shù)據(jù)集,較少使用隨機(jī)生成的測試數(shù)據(jù)。
靜態(tài)分析部可以檢查代碼、實(shí)現(xiàn)邏輯,遍歷MVC體系結(jié)構(gòu)的各層。動態(tài)檢測本身無法解析代碼,因此,本次設(shè)計的靜態(tài)分析、動態(tài)分析組合框架的靜態(tài)分析部分不是完全獨(dú)立的,而是具有兩個重要的接口,即輸入接口、輸出接口。輸入接口的定義是URL參數(shù)的map/list結(jié)構(gòu),來自動態(tài)分析得到的值域序列轉(zhuǎn)換而來,將URL參數(shù)的map/list結(jié)構(gòu)并傳輸給靜態(tài)分析部分。靜態(tài)分析包括一個專門開發(fā)的模塊識別部分。將該數(shù)據(jù)結(jié)構(gòu)與路由代碼的詳細(xì)邏輯相結(jié)合以進(jìn)行靜態(tài)分析,從而在數(shù)據(jù)結(jié)構(gòu)中的參數(shù)值域中找到“路由”,并基于不同的值域按照不同用戶自定義的分析邏輯對代碼進(jìn)行分析[3]。例如,如果靜態(tài)程序輸入接口接收到圖2中所示的數(shù)據(jù)結(jié)構(gòu)時,會從Web應(yīng)用程序的“路由”代碼查找role,moduie,op的相關(guān)部分,再用[userir,info,show]等值域集合找到程序代碼,然后進(jìn)行靜態(tài)分析。

圖2 URL參數(shù)map/list結(jié)構(gòu)
靜態(tài)分析的輸出接口主要用于為動態(tài)檢測的第二次啟動提供數(shù)據(jù),提取與MVC體系結(jié)構(gòu)應(yīng)用程序的各個分支代碼相對應(yīng)的各種路由參數(shù),并通過對代碼部分(尤其是路由代碼部分)的詳細(xì)分析來獲得其完整值域。通過輸出接口傳輸值域給動態(tài)分析模塊,有效彌補(bǔ)動態(tài)分析的不足。
本次研究的動態(tài)分析+靜態(tài)分析的檢測模式中的動態(tài)分析需要啟動兩次,這是該模式的重要特點(diǎn)。動態(tài)分析第一次啟動時進(jìn)行純動態(tài)檢測,識別過程屬于傳統(tǒng)的動態(tài)識別方法。識別結(jié)果分為兩部分:第一部分,獲得的部分檢測結(jié)果用作最終的動態(tài)分析結(jié)果;第二部分,獲得的URL參數(shù)域和值域,作為參數(shù)傳送給靜態(tài)分析模塊。靜態(tài)分析接收參數(shù),進(jìn)行分析后返回值域參數(shù)給動態(tài)分析模塊,以補(bǔ)充第一次動態(tài)分析獲得的URL參數(shù)值域,從而得到完整的值域。在進(jìn)行邏輯判斷后,動態(tài)分析模塊將第二次啟動,再次執(zhí)行動態(tài)檢測和分析,以補(bǔ)充完善第一次動態(tài)檢測分析的結(jié)果。
綜上所述,目前,網(wǎng)絡(luò)安全攻擊手段越來越多,PHP語言開發(fā)的Web應(yīng)用是網(wǎng)絡(luò)黑客的攻擊重點(diǎn)。如果未及時發(fā)現(xiàn)代碼缺陷,找出安全漏洞,就容易被黑客攻擊破壞。本文提出了一種靜態(tài)分析和動態(tài)分析相結(jié)合的PHP代碼缺陷檢測方案。但要真正實(shí)現(xiàn)此方案是非常復(fù)雜的工程,需要后續(xù)進(jìn)行不斷研究。