選單

程式碼審計之論

程式碼審計現狀

隨著開發人員的安全意識逐步提高,導致漏洞挖掘的難度逐年遞增。而程式碼審計,逐漸出現在大家的視野裡,方便了安全人員能夠更易挖掘到很多黑盒測試不容易發現的漏洞威脅。但是由於系列程式碼審計從0到1的資料比較稀缺,導致懂程式碼審計的人相對屬於少數人員,而大部分web安全人員還徘徊在已知漏洞利用階段。

程式碼審計之問

有大部分小夥伴沒有真正接觸程式碼審計,沒有具體去實踐程式碼審計的肯定會有這樣的疑問。要做程式碼審計需要懂哪些知識啊?給一套程式如何下手?我看得懂別人的程式碼審計案例,但是到自己下手時就沒了思路了呢?找到漏洞不會構造POC 怎麼辦等等。筆者認為問這些問題的主要原因是不知道程式碼審計的流程。如果你知道程式碼審計的流程,你就知道哪個環節需要學習掌握哪些知識;如何下手審計程式碼;選擇什麼樣的方式去下手;如何構造Payload,編寫POC來驗證漏洞的存在。

筆者認為程式碼審計的流程是:審計前的準備->定位漏洞產生點->URL連結構造訪問漏洞產生點->payload構造突破各種防禦/編碼轉換->證實漏洞存在。下面我們以php程式碼審計為例來進行分析。

審計前的準備

環境搭建+除錯工具

別人給我們一套php程式讓我們做程式碼審計,透過漏洞挖掘驗證漏洞的存在。我們在拿到程式之後,首先要做的是環境搭建,讓程式執行起來方便我們除錯,驗證。這就要求懂得windows版的php環境搭建或者linux版的php環境搭建。筆者推薦一款整合開發環境phpstudy。這款整合環境不論是windows還是linux安裝方便,php版本切換一鍵搞定。環境搭建完畢後,我們要使用編輯器去修改程式碼除錯程式,這裡推薦使用IDE,phpstrom。該款編輯器美化精緻,功能強大,可在phpstrom上配置xdebug 來進行除錯方便漏洞挖掘。所以這裡我們要學習phpstrom的簡單使用及關鍵詞搜尋與xdebug的配置。

定位漏洞發生點

尋找定位漏洞發生點一般有如下幾種方式。

1全文通讀正向審計

2功能點審計

3關鍵詞定位逆向追蹤

4灰盒+白盒審計

在進行程式碼審計的時候,各種方式進行組合使用是比較高效的,當然這是對有審計經驗的人來說的,沒有的還是慢慢針對一種方式練習一下。

在尋找漏洞定位漏洞發生點之前,審計者首先要清楚自己的定位,想要挖單種類型的漏洞,常規型別漏洞,還是業務型別邏輯漏洞,是想挖掘哪些比較難發現的漏洞,還是想挖掘比較容易挖掘的漏洞。挖掘什麼樣的漏洞,你就要熟悉什麼樣的漏洞型別產生原理,知道哪些函式利用不當或本身的脆弱性或未過濾/有效過濾造成的漏洞威脅。 比如涉及到sql注入時,因為它的產生是可控引數在與資料庫互動的時沒有有效過濾與原有SQL語句拼接在一起造成的注入漏洞,這時你就要專門查詢與資料庫互動的功能;又比如XSS, 它是在瀏覽器渲染的時候,可控引數被當做js程式碼執行造成的,這時候你就要查詢在輸出端時,可控引數會不會被導致js執行。其他常規型別漏洞挖掘時,可直接定位關鍵詞來回溯。 挖掘單種類型漏洞或者常規型別漏洞,可以使用自動化審計工具如國際流行的rips,國內seay大牛的原始碼審計工具,進行關鍵詞定位搜尋,然後在去驗證漏洞的存在及可用性。

全文通讀正向審計並非程式碼全讀,且屬於正向追蹤。審計框架級的程式,先找出開發手冊來熟悉一下,然後在根據手冊挑出有可控點的方法往下追程式碼,如帶入了哪個方法,呼叫了哪個函式,一直追到不能追了或者追到有漏洞點位置為止,這樣的好處是漏洞發現的覆蓋率高,追蹤好追蹤,url連結好構造;審計沒有手冊的程式,就專門找URL連結可直接請求到的方法,且該方法中程式碼有帶可控點方法呼叫,然後如上追程式碼。例如請求的url連結是localhost/user/updatePassword,這個連結對映的程式碼位置是user模組的updatePassword方法,該方法中有程式碼$User->where(‘id=’。$_GET[‘id’])->save(); 我們看到where()方法中有帶入可控引數id,那我們就繼續往下追蹤where方法去尋找漏洞發生點。

功能點審計適用於常規型別漏洞,也適用於邏輯型別漏洞。為什麼這麼說呢?比如一個忘記密碼找回的功能點,我們猜測該功能點可能會有SQL注入,驗證碼繞過,爆破重置密碼,越權等漏洞,所以我們在審計功能點的時候,就會著重進行預測漏洞型別的審計。一般有了一定程式碼審計經驗的人在做SDL的威脅建模時,效率就會高很多。

URL連結構造訪問漏洞產生點

到了這個環節,必不可少的要熟悉程式的目錄檔案結構,URL路由。一般訪問漏洞產生點會有兩種方式,一種是透過URL連線構造直接訪問和間接訪問。直接訪問是漏洞產生點在可透過URL直接對映到的方法中,間接方法是漏洞點在直接對映的方法內所呼叫的其他方法(可多級遞迴)中。想要學會URL構造,一般有三種方式,①網站連結點選+目錄結構尋找控制器方法。隨便點選搭建起來的目標網站連結,透過對比連結,和目錄檔案結構來模仿構造URL連結②看手冊找到URL路由結構的對映方式③是看程式碼+經驗。

PAYLOAD構造

一般可控引數在到漏洞發生點時,可能會遇到程式碼防禦過濾,型別轉換,編碼轉換等。所以在可控引數到漏洞發生點期間,進行了哪些,防禦,轉換,編碼等做一個流程圖,在最後漏洞發生點想要執行什麼樣的結果,寫出來,然後拿著最後執行的效果往上推,一直推到可控引數傳參的位置。在這個環節,必不可少的要掌握一些滲透技巧,跟payload編寫技巧,方便在用到的時候能真正做到靈活運用。

其他

在程式碼審計時,我們不光要注意到程式碼的問題,還要注意到php。ini配置問題,中介軟體結合的問題等各種影響因素,而且在審計一套你未曾審計的原始碼時,可查閱一下前輩們審計的該套目標程式的漏洞產生情況,熟悉開發人員的開發安全意識及漏洞忽略點來進行漏洞預測挖掘。

總結一下,透過上面簡單的論述,對程式碼審計已經有了一個初步的瞭解,掌握了程式碼審計,你不光熟悉了程式語言,滲透測試技巧,更學會了漏洞挖掘,也就是說你同時掌握了三種技術。

喜歡就點個關注唄~謝謝