1. 程式人生 > >PHP程式碼審計學習

PHP程式碼審計學習

這是一次分享準備。
自己還沒有總結這個的能力,這次就當個搬運工好了~~

0x01 工具準備

PHPSTORM,不只是程式設計。

個人覺得只要能夠提供全域性搜尋、單頁搜尋、函式跳轉的編輯器就能夠滿足要求。一般在審計的時候,先找到一個入口點,配合程式碼和瀏覽器,一邊下斷點,一邊列印變數,再在瀏覽器上觀察反應。

自動化審計工具,食之無味,棄之可惜。

當然,我手邊能用到的自動化審計工具就是能在網上找到資源的那幾種。對於快速定位漏洞點來審計,自動化工具是有一定作用的,但是,大多數我能接觸到的審計工具大抵是基於規則匹配的或者有一定的資料流向,但由於不能做到語義識別,很多邏輯控制語句無法識別,導致敏感點可可控引數無法自由的跳轉結合。

現在的習慣是,有了程式碼,先會扔進審計工具裡跑一跑,看一個大概趨勢,如果時間充裕,一般還是願意一點一點從程式碼入口點跟進。

0x02 審計初步

審計可以從多個角度切入,首先是搞清楚審計物件的架構,是套了開源的框架,還是原生程式碼;是MVC,還是僅僅是函式呼叫。

那麼在審計之前,最好就是使用或者熟悉這些常見框架的特性機制。

CI
https://codeigniter.org.cn/

YII2http://www.yiichina.com/

ThinkPHPhttp://www.thinkphp.cn/

Laravelhttps://laravel.com/

熟悉這些框架方便我們快速判斷審計點。比如之前的一次程式碼審計就是套了ThinkPHP的核心程式碼,結果導致ThinkPHP的漏洞對於那套系統依然適用。

為了能夠邊學習邊實踐別人的思想,我這裡以MetInfo為例進行學習。

對於快速審計,比如自動化工具,往往可以考慮以下一些切入點。

敏感函式切入

敏感函式包括能夠程式碼執行(PHP、MYSQL)的函式、上傳下載檔案的函式、檔案讀取的函式、載入資源的函式。

  • eval()- 海洋CMS6.28

@eval(“if(“.$strIf.”){\$ifFlag=true;}else{\$ifFlag=false;}”);

  • exec()-imo雲辦公

$result = exec($_POST[‘command’]);

  • preg_replace()-Thinkphp2.1

preg_replace(‘/test/e’, ‘phpinfo()’, ‘just test’);

preg_replace(‘@(w+)’.$depr.’([^’.$depr.’\/]+)@e’, ‘$var[\’\1\’]=”\2”;’, implode($depr,$paths));

……

這一類的函式有很多,這種漏洞一般可能會呈現兩種趨勢,一種就是常用函式過濾繞過,一種是不常見函式用法失誤的。

漏洞點切入

如果說白盒找敏感函式的話,黑盒上對應的就是優先查詢程式的SQL執行點、上傳點、登入點、密碼找回點等

登入頁面、表單接收頁面、資訊顯示頁面

普通拼接,這種不多說了,主流開源的程式碼想挖到這種已經很難了,要麼沒有拼接的用法,要麼就做了更加嚴格的過濾。

當然,這裡有些小技巧,比如多次過濾情況下的繞過。如\include\mail\class.phpmailer.php的1741行:

tip1:
$textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s','',$message))); 

這裡連續用了兩個過濾函式,這兩個函式在一起容易造成繞過。

可以使用這兩個payload做對比:

<head>evil</head>

<he<>ad>evil</head>

編碼注入:

二次編碼注入,addslashes、mysql_real_escape_string、mysql_escape_string或者開啟GPC來轉義,但是,如果再次使用urlencode就會出現二次編碼。

  • 檔案包含

模組載入,模板載入,cache呼叫

  • 任意檔案讀取

尋找檔案讀取敏感函式

  • 檔案上傳

move_uploaded_file()

  • 檔案刪除

unlink()

  • 變數覆蓋

extract()

parse_str()

$$

index切入

從軟體的index入口點開始,逐漸遍歷到所有函式檔案。

0x03 審計實踐

這裡以Metinfo為例進行演示,先大致瞭解一下該款CMS的結構。

根目錄下入口index.php,前臺客戶邏輯在/member/裡,後臺邏輯在/admin/裡,自己建立的應用在/app/中,
前臺的下載/搜尋/等邏輯對應在相應的目錄下。

常用的功能函式集中在/include/下,重點在*.inc.php和*.func.php中

/index.php
    |
/include/common.inc.php

這個檔案很有意思,比如裡面有名的變數覆蓋,由變數覆蓋處跳轉到過濾函式daddslashes(),明顯這裡有國瓷打補丁的痕跡,分享時現場細說,這裡就不贅述。
/include/common.inc.php
|

/include/head.php
    |
/app/
    |
/include/

MetInfo由於特殊的變數傳遞機制和路由機制,使得我們可以輕易訪問到任意PHP檔案並且攜帶引數進行測試,所以對於它的審計順序會更加鬆散一點。

我這裡先從關聯性較弱的/about/,/upload/,/search/等幾個資料夾看起,最後再集中閱讀使用者應用的/app/資料夾。

利用前面說到的斷點輸出變數的方法一點一點除錯例項,分享用。

http://127.0.0.1/case/index.php?metid=1&filpy=&fmodule=0&modulefname=2)

到這裡都沒有什麼太大的發現,唯一的感受就是有很多點都很驚險,由於沒有用MVC框架,顯然很多SQL語句之間的寫法差異都比較大。

之後就可以跟進include的功能函式來看,也就是在這裡終於知道了一個小漏洞。

前臺大概看得差不多,就可以跟進後臺admin資料夾看看,這裡就會覺得輕鬆很多,一個後臺就不在適用過濾函數了,另一個後臺功能更多一點,不過後臺漏洞大多就只能算程式碼BUG,沒有前臺來得那麼驚豔。

大多數的內容打算分享的時候直介面述,這裡其實只能算是一個大綱,所以文字上可能不是很通順。