程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> 淺談PHP自動化代碼審計技術,淺談php自動化審計

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

編輯:關於PHP編程

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


原文出處: exploit   歡迎分享原創到伯樂頭條

0×00

 

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

 

0×01

 

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

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

 

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

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

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

4、漏洞代碼分析模塊
該模塊基於數據流分析模塊收集的全局變量、賦值語句等信息,進行污點數據分析。主要針對敏感sink中的危險參數,如mysql_query函數中的第一個參數,經過回溯獲取到相應的數據流信息,如果在回溯過程中發現該參數有用戶控制的跡象,就進行記錄。如果該危險參數有相應的編碼、淨化操作也要進行記錄。通過對危險參數的數據進行跟蹤和分析,完成污點分析。

 

0×02

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

 

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

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。並且要對危險函數中的危險參數做有效的分析,這些分析包括判斷是否進行了有效的淨化(比如轉義、正則匹配等),以及制定算法來回溯前面該變量的賦值或者其他變換。這無疑對安全研究人員工程能力的一個考驗,也是自動化審計最重要的階段。

 

0×03

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

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved