淺談PHP自動化代碼審計技術____PHP

來源:互聯網
上載者:User
0x00

由於部落格實在沒什麼可以更新的了,我就把目前做的事情總結一下,當做一篇部落格,主要是談一談項目中所運用的一些技術。目前市面上有不少PHP的自動化審計工具,開源的有RIPS、Pixy,商業版本的有Fortify。RIPS現在只有第一版,由於不支援PHP物件導向分析,所以現在來看效果不是太理想。Pixy是基於資料流分析的工具,但是只支援PHP4。而Fortify是商業版本,由於這個限制,對它的研究也就無從談起。國內對於PHP自動審計的研究一般都是公司在做,目前有些工具大多數使用簡單的token串流分析或者直接粗暴一些,使用Regex來匹配,效果會很一般。

  0x01

今天所要談的技術是基於靜態分析的一種PHP自動化審計的實現思路,也是我的項目中的思路。為了進行更加有效變數根據和汙點分析,以及很好的應對PHP指令碼中的各種靈活的文法表示,Regex效果肯定是不理想的,我所介紹的思路是基於代碼靜態分析技術和資料流分析技術的審計。

首先,我認為一個有效審計工具至少包含如下的模組:

1、編譯前端模組

編譯前端模組主要運用編譯技術中的抽象文法樹構建、控制流程圖構建方法,將源碼檔案轉為適合後端靜態分析的形式。

 

2、全域資訊搜集模組

該模組主要用於對分析的源碼檔案進行統一的資訊搜集,比如搜集該審計工程中有多少類的定義,並對類中的方法名、參數、以及方法定義代碼塊的起始和終止的行號進行搜集,用於加快後續的靜態分析的速度。

 

3、資料流分析模組

該模組不同於編譯技術中的資料流分析演算法,在項目中更注重對PHP語言本身特性的處理。當系統的過程間和過程內分析過程中發現了敏感函數的調用,則對該函數中敏感的參數進行資料流分析,即跟蹤該變數的具體變化,為後續汙點分析做準備。

 

4、漏洞程式碼分析模組

該模組基於資料流分析模組收集的全域變數、指派陳述式等資訊,進行汙點資料分析。主要針對敏感sink中的危險參數,如mysql_query函數中的第一個參數,經過回溯擷取到相應的資料流資訊,如果在回溯過程中發現該參數有使用者控制的跡象,就進行記錄。如果該危險參數有相應的編碼、淨化操作也要進行記錄。通過對危險參數的資料進行跟蹤和分析,完成汙點分析。 0x02

有了模組,那麼如何進行有效流程來實施自動化審計,我使用了如下的流程:

分析系統經過的大致流程如下:

1、架構初始化

首先進行分析架構的初始化工作,主要是搜集待分析源碼工程中的所有使用者自訂類的資訊,包括類名,類屬性,類方法名,類所在的檔案路徑。

這些Record存放在全域上下文類Context中,該類使用單例模式進行設計,並且常駐記憶體,便於後續的分析使用。

 

2、判斷Main File

其次判斷每個PHP檔案是否是Main file。在PHP語言中,沒有所謂的main函數,大部分Web中的PHP檔案分為調用和定義兩種類型,定義類型的PHP檔案是用來定義一些業務類、工具類、工具函數等,不提供給使用者進行訪問,而是提供給調用類型的PHP檔案進行調用。而真正處理使用者請求的則是調用類型的PHP檔案,比如全域index.php檔案。靜態分析主要是針對處理使用者請求的調用類型的PHP檔案,即Main File。判斷依據為:

在AST解析完成的基礎上,判斷一個PHP檔案中的類定義、方法定義的程式碼數占該檔案所有程式碼數是否超過一個範圍,如果是,則視為定義類型的PHP檔案,否則為Main File,添加到待分析的檔案名稱列表中。

 

3、AST抽象文法樹的構建

本項目基於PHP語言本身進行開發,對於其AST的構建,我們參考目前比較優秀的PHP AST構建的實現————PHP Parser。

該開源項目基於PHP語言本身進行開發,可以對PHP的大多數結構如if、while、switch、數組聲明、方法調用、全域變數等文法結構進行解析。可以很好的完成本項目的編譯前端處理的一部分工作。

 

4、CFG流圖構建

使用CFGGenerator類中的CFGBuilder方法。方法定義如下:

具體思路是採用遞迴構建CFG。首先輸入遍曆AST擷取的nodes集合,遍曆中對集合中的元素(node)進行類型判斷,如判斷是否是分支、跳轉、結束等語句,並按照node的類型進行CFG的構建。

這裡對於分支語句、迴圈語句的跳轉條件(conditions)要儲存至CFG中的邊(Edge)上,方便資料流分析。

 

5、資料流資訊的收集

對於一段代碼塊,最有效並且值得收集的資訊是指派陳述式、函數調用、常量(const define)、註冊的變數(extract parse_str)。

指派陳述式的作用就是為了後續進行變數跟蹤,在實現中,我使用了一種結構來表示賦值的value以及location。而其他的資料資訊是基於AST來判別和擷取的。比如函數調用中,判斷變數是否受到轉義、編碼等操作,或者調用的函數是否是sink(如mysql_query)。

 

6、變數淨化、編碼資訊處理

$clearsql = addslashes($sql) ;

指派陳述式,當右邊是過濾函數時(使用者自訂過濾函數或者內建過濾函數),則調用函數的傳回值被淨化,即$clearsql的淨化標籤加上addslashes。

發現函數調用,判斷函數名是否是設定檔中進行配置的安全函數。

如果是,則將淨化標籤添加至location的symbol中。

 

7、過程間分析

如果在審計中,發現使用者函數的調用,這時候必須要進行過程間的分析,在分析的工程中定位到具體方法的代碼塊,帶入變數進行分析。

痛點在於,如何進行變數回溯、如何應對不同檔案中的相同名稱的方法、如何支援類方法的調用分析、如何儲存使用者自訂的sink(比如在myexec中調用exec函數,如果沒有經過有效淨化,那麼myexec也要視為危險函數)、如何對使用者自訂的sink進行分類(如SQLI XSS XPATH等)。

處理流程如下:

8、汙點分析

有了上面的過程,最後要進行的就是汙點分析,主要針對系統中內建的一些風險函數,比如可能導致xss的echo。並且要對危險函數中的危險參數做有效分析,這些分析包括判斷是否進行了有效淨化(比如轉義、正則匹配等),以及制定演算法來回溯前面該變數的賦值或者其他變換。這無疑對安全研究人員工程能力的一個考驗,也是自動化審計最重要的階段。

 

  0x03

通過上面的介紹,你可以看到要實現一款自己的自動化審計工具所要趟的坑是很多的。我的嘗試中也是遇到了N多的困難,並且靜態分析確實帶有一定的局限性,比如動態分析中輕易可以獲得的字串變換的過程,在靜態分析中就難以實現,這不是技術上能夠突破的,而是靜態分析本身的局限性導致的,所以單純的靜態分析如果想要做到誤判和漏報很低,畢竟引入一些動態思想,比如對eval中的代碼進行類比,對字串變化函數以及Regex進行處理等。還有就是對於一些基於MVC架構的,比如CI架構,代碼很分散,比如資料淨化的代碼放在input類的擴充中,像這種PHP應用,我認為很難做到一個通用的審計架構,應該要單獨對待。

以上只是粗略的把我當前的嘗試(目前沒有完全實現)拿來share,畢竟大學狗不是專業人員,希望可以拋磚引玉,使得越來越多的安全研究人員關注這一領域。


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.