PHP程式碼審計學習總結

cnbird發表於2013-03-06

0×01 引言

PHP是一種被廣泛使用的指令碼語言,尤其適合於web開發。具有跨平臺,容易學習,功能強大等特點,據統計全世界有超過34%的網站有php的應用,包 括Yahoo、sina、163、sohu等大型入口網站。而且很多具名的web應用系統(包括bbs,blog,wiki,cms等等)都是使用php 開發的,Discuz、phpwind、phpbb、vbb、wordpress、boblog等等。
隨著web安全的熱點升級,php應用程式的程式碼安全問題也逐步興盛起來,越來越多的安全人員投入到這個領域,越來越多的應用程式程式碼漏洞被披露。面對 這種現狀,PHP漏洞“挖掘者”所能得到的漏洞也將越來越少。但是“窮則思變”,既然傳統的審計方法不能達到挖掘漏洞的目的,那麼我們何不嘗試新的審計手 法與思路呢?
在這篇文章中,主要提供給大家的是我在學習PHP程式碼審計過程中,所獲得的一些經驗,以及對審計過程的思考。文章內容所提及的內容很淺,但是希望能給大家帶來一些思路,對於程式碼審計或者漏洞挖掘能有新的思考。

0×02 審計之初

程式碼審計的目的是以挖掘到可以利用的漏洞,所以我們不必通篇的去將程式碼完全看懂,但是在開始之前做一些準備還是必須,就像滲透之前,我們也需要收集足夠多的目標資訊,利用工具和制定滲透計劃一樣。

2.1  流程

在我剛開始練習審計時,拿到一套原始碼,馬上做的事情就是,丟到工具裡,去掃敏感的函式,然後去一個一個的回溯它,找到入口點。但是,這樣審計了幾套源 碼,發現這個方法很浪費時間,因為每次我都要在回溯過程中,不斷的去尋找原始碼中定義的一些通用函式。由於不瞭解整個原始碼的流程,導致在找這些通用函式的過 程中浪費了很多的時間與精力。
所以,我重新調整了我的審計流程。在拿到原始碼之後,先從它開始的地方(一般是根目錄下的index檔案)按照執行的順序去讀程式碼,一直到它的初始化內容, 和基本功能實現完畢為止。這樣,可以明確的瞭解整套原始碼的結構,哪一種函式檔案放在哪個資料夾下;知道通用函式放在哪個檔案中。這對我們在之後閱讀“疑 似”有問題的程式碼時,有很好的幫助,例如,在看到一個通用函式時,我們可以快速的切換到通用函式檔案,查詢這個函式的實現程式碼。這個方法帶來好處還有好 多,這裡就不一一列出了。

2.2  瞭解

流程的優化可以幫助我們在之後審計的過程中,免去時間和精力上不必要的浪費。而在深入閱讀程式碼之前,瞭解整套程式碼的每一個功能點,每一個輸入框和他曾經出現的漏洞及相關修補方案,將會大大提高我們在之後的審計效率。
在瞭解原始碼的每個功能時,如果你能夠注意以觀察url的變化,也許能你在後面的閱讀帶程式碼過程中跳過很多沒用的分支。
而在測試每一個輸入框時,如果你仔細觀察HTML原始碼中輸入框的id或者name,這也許能幫你在後面的審計過程中更快的定位到利用點。
嘗試瞭解這套原始碼曾經出現過的漏洞,以及相關的修補方案,這是程式碼審計中的一條不錯的捷徑。因為一套原始碼雖然可能不是一個人完成的,但是它肯定是基於一 個框架的,為這套原始碼編碼的程式設計師們都會圍繞著這個框架進行開發,他們肯定必須要遵守框架的規則,而瞭解這些曾經出現過的這些漏洞,說不定可以發現他們所 共有的陋習。如果你能夠了解這些漏洞修補的詳細細節,那就更好了,因為隨著Web平臺的升級變遷,或者新的技術出現,這些修補也許就會變成擺設。

2.3  計劃

有計劃地做事,這是一個很好的習慣。計劃可以幫助我們明確我們取得了什麼樣的成果就可以稱之為成功,面臨什麼樣的問題才可以稱之為失敗。這樣可以避免我們可能因為某天的情緒不佳而“果斷”的放棄,也可以避免我們將時間不斷地投向一個不可能完成的任務。
我在程式碼審計學習過程中,總結有兩點是在前期計劃必須明確的,
1.        要找什麼樣的漏洞
2.        要花多長時間完成這次審計
明確找什麼樣的漏洞,能夠方便我們在收集相關資料(如:引發問題的函式字典)時的目標更精準,收集資料更全面。
確定整個審計的時間範圍,一時間作為審計的量化標準,可以準確的定位審計是否成功,當然,在不同的情況或者過程中,計劃時間是可以調整的

0×03  漏洞本質

程式的本質是變數與函式,漏洞所依賴的也無法脫離這兩個元素。讓我們先來看下漏洞形成的條件
1.        可以控制的變數【一切輸入都是有害的 】
2.        變數到達有利用價值的函式[危險函式] 【一切進入函式的變數是有害的】
漏洞的利用效果最終也取決與函式的功能。所以我們在下面講述漏洞挖掘的過程中,也將圍繞著這兩個元素來展開。

0×04  漏洞挖掘

這章所講的內容,不會很深入的講述漏洞挖掘的技巧,因為每一種技巧都肯能會涉及到一種技術,單單一個技巧就可以作為一篇文章來發表了。所以我在這章中所 講述的,只是漏洞挖掘中很基礎的內容。目的也很簡單,做個比喻來說,我只是為被大火困在高樓中的人們開啟一扇窗,至於如何爬下這棟樓,這章中不會有涉及。 當然,如果你覺得你可以走樓梯,也是不錯的。
在上一章中,我們提到漏洞形成的兩大元素是可控變數,和可控變數能夠進入的函式。那麼在漏洞挖掘中,我們也不外乎從這兩個方向來開始。
1.png
從變數開始跟蹤,我們就好像處在下圖中圓形的位置,我們要處理的“路”很多,但不是每條“路”都能到達三角形(函式)。
2.png
所以在一般的人工程式碼審計過程中,大都會選擇查詢危險函式,然後根據危險函式中的變數回溯到傳入變數的方式。
我的審計方法也是偏向於通過函式查詢變數,雖然這種方式效果很好,但是我們也不應放過變數跟蹤。如果你擁有一款不錯的變數跟蹤自動化工具,那麼你很 幸運,不用花費很大的精力便可以完成這個任務。如果你是手工審計的話,我建議,你在跟蹤函式之前,收集所有可控變數(引數)的“最終形態”(所謂最終形 態,就是使用者通過各種方式傳入程式序經過各種處理後,等待呼叫時的形態)。這樣可以幫助我們能夠在跟蹤危險函式時,更快的確定,函式是否能被利用。

0×05 總結

在這部分內容,給出大家一些,我在學習過程中摸索到的一些不錯的方法和學習審計中所必須要積累的一些內容。

5.1  積累

1.        對於爆出的每種漏洞,都要對其進行分析瞭解(PoC學習)
2.        對於已修復漏洞,對其補丁或修復方法進行分析瞭解(DEDE,discuz全域性變數覆蓋漏洞的二次利用)
3.        平臺搭建的通用配置和常用配置要了解

5.2  練習

1.        閱讀大的原始碼,瞭解程式碼執行流程
2.        挖掘小型原始碼漏洞,實踐+信心
3.        PoC的編寫,深入理解漏洞利用過程

0×06 思考

在這一章節中,我將羅列出我在學習和練習程式碼審計過程中所想到,但是卻沒有得到答案的問題。希望能給大家帶來思考的同時,也能讓大家發現新的思路

6.1  如何跳出傳統的思維

很多應用程式的官方都成立了安全部門,或者僱傭安全人員進行程式碼審計,因此出現了很多自動化商業化的程式碼審計工具。也就是這樣的形勢導致了一個局面:大公司的產品安全係數大大的提高,那些很明顯的漏洞基本滅絕了,那些大家都知道的審計技術都無用武之地了。
沒有絕對安全的程式碼,我們需要跳出傳統的思維,來獲得新的漏洞。這也就是所謂的“跳出畫來看畫”,但是如何跳出來,這是我們當前所要思考的地方。

6.2  變數跟蹤自動化的可行性

在學習和練習程式碼審計的過程中,我沒有發現一款能夠進行變數跟蹤的自動工具,大多數都是搜尋危險函式的工具。傳統的程式碼審計都是基於靜態的,而變數跟蹤需要動態的實現,這也是導致跟蹤變數,工作量大的主要原因。
基於這個問題,自己有個想法,可以在一款程式碼除錯工具中新增特定變數發生改變或進入某些函式之前執行暫停的功能。這樣,我們在程式碼審計的過程中便可以設定我們需要跟蹤的可控變數,當其值發生變化時,能夠馬上了解它的情況。
也可以製作一個指令碼,能夠羅列出特定變數所必須或者有可能經歷的函式。這樣我們可以結合危險函式跟蹤的結果進行交集的查詢,大大的提高了效率和效果。

0×07  引用

1.        《WEB程式碼審計與滲透測試(PPT)》by 80vul
2.        《高階PHP應用程式漏洞稽核技術》by 80vul
3.        《例項分析講解為您敲開程式碼審計大門》by 90sec

原文:https://www.t00ls.net/thread-20855-1-1.html 作者 唐門三少

本文由網路安全攻防研究室(www.91ri.org)資訊保安小組收集整理,轉載請註明出處。


相關文章