官术网_书友最值得收藏!

3.1 代碼審計(jì)的思路與流程

在代碼審計(jì)工作中,最重要的是思路。每個(gè)人的思路不一樣,經(jīng)驗(yàn)不一樣,直觀感覺(jué)與理解也自然不同。下面筆者將介紹從實(shí)踐中總結(jié)出來(lái)的經(jīng)驗(yàn),包括代碼審計(jì)的難點(diǎn)、思路和流程。

3.1.1 代碼審計(jì)的難點(diǎn)

代碼審計(jì)的難點(diǎn)如下。

●代碼看不懂,如缺乏編程語(yǔ)言基礎(chǔ)、數(shù)據(jù)庫(kù)基礎(chǔ)、操作系統(tǒng)基礎(chǔ)等。

●URL鏈接不會(huì)構(gòu)造,如缺乏框架使用基礎(chǔ)、網(wǎng)站運(yùn)行基礎(chǔ)等。

●方法的調(diào)用看不懂,如函數(shù)的作用、函數(shù)如何調(diào)用等。

●代碼追蹤復(fù)雜,如函數(shù)在各個(gè)文件的調(diào)用、各個(gè)方法的調(diào)用等。

●漏洞類(lèi)型原理不熟悉,如Web前端漏洞基礎(chǔ)、Web后端漏洞基礎(chǔ)等。

●不會(huì)繞過(guò)各種障礙,如限制繞過(guò)基礎(chǔ)、參數(shù)突破基礎(chǔ)等。

以上問(wèn)題導(dǎo)致了即使從其他渠道獲取了漏洞POC(即驗(yàn)證代碼),也不知道如何寫(xiě)出來(lái)的。本書(shū)將漏洞原理進(jìn)行層次化的剖析,以達(dá)到快速進(jìn)行代碼審計(jì)的目的。

主要通過(guò)以下幾點(diǎn)進(jìn)行詳解。

●目錄結(jié)構(gòu)。通過(guò)目錄結(jié)構(gòu)可以知道是什么開(kāi)源程序,這對(duì)熟悉程序調(diào)用是必不可少的。

●URL鏈接構(gòu)造。通過(guò)了解URL構(gòu)造技巧,可以很方便地構(gòu)造POC。

●漏洞位置定位。

●代碼追蹤。

●POC構(gòu)造。

對(duì)于一些新手來(lái)說(shuō),建議從審計(jì)簡(jiǎn)單的漏洞開(kāi)始,例如先通過(guò)直接搜索關(guān)鍵詞、進(jìn)行逆向追蹤、使代碼審計(jì)工具輔助(例如seay源代碼審計(jì)工具)篩選出可能存在的漏洞點(diǎn),然后再追蹤代碼來(lái)分析和驗(yàn)證漏洞觸發(fā)條件。

3.1.2 代碼審計(jì)流程

代碼審計(jì)需要一個(gè)流程化的步驟來(lái)發(fā)現(xiàn)安全問(wèn)題,可以參考以下流程來(lái)進(jìn)行漏洞挖掘,即漏洞挖掘五步走。

1)尋找漏洞。

2)URL構(gòu)造,訪(fǎng)問(wèn)到漏洞發(fā)生點(diǎn)的URL地址。

3)漏洞挖掘查詢(xún)可控參數(shù)到漏洞發(fā)生點(diǎn)經(jīng)過(guò)了哪些轉(zhuǎn)換(可采用phpStorm+Xdebug進(jìn)行調(diào)試分析,厘清可控參數(shù)到漏洞發(fā)生點(diǎn)的數(shù)據(jù)處理過(guò)程)。

4)防御突破。

5)構(gòu)造Payload,驗(yàn)證漏洞真實(shí)性。

這種代碼審計(jì)方式屬于關(guān)鍵詞定位結(jié)合逆向追蹤參數(shù)溯源類(lèi)型,通過(guò)以上步驟進(jìn)行安全問(wèn)題的探索,可以探索出更多安全漏洞。下面詳細(xì)講解這五步。

1.尋找漏洞

尋找漏洞一般有以下幾種方法。

●全文通讀結(jié)合功能點(diǎn)審計(jì)。

●關(guān)鍵詞定位結(jié)合逆向追蹤參數(shù)溯源。

●預(yù)測(cè)功能點(diǎn)漏洞結(jié)合功能點(diǎn)定向?qū)徲?jì)。

●灰盒測(cè)試結(jié)合代碼審計(jì)。

對(duì)于一些新手來(lái)說(shuō),想要嘗試挖掘應(yīng)用系統(tǒng)源代碼存在的漏洞,最快的方式就是搜索關(guān)鍵詞。比如,要尋找代碼執(zhí)行的漏洞,就搜索可以觸發(fā)代碼執(zhí)行的函數(shù)關(guān)鍵詞。這里的函數(shù)關(guān)鍵詞就是指代碼當(dāng)中所使用的一些編程語(yǔ)言自身所提供的功能函數(shù),例如assert。

假設(shè)想要挖掘包含漏洞(包含漏洞會(huì)在第7章中介紹),可嘗試在該源代碼中搜索帶有包含引用的函數(shù),如關(guān)鍵詞include。找到引用的函數(shù)之后,再?gòu)脑摯a功能實(shí)現(xiàn)的邏輯順序從下往上推。如果這個(gè)功能或某個(gè)參數(shù)不可控的話(huà),那么在外面復(fù)現(xiàn)或挖掘該漏洞時(shí)就會(huì)出現(xiàn)很多問(wèn)題,最終可能會(huì)導(dǎo)致漏洞無(wú)法復(fù)現(xiàn)。

若參數(shù)可控且無(wú)任何安全機(jī)制或有效安全機(jī)制檢查,可通過(guò)URL構(gòu)造鏈接編寫(xiě)POC,以證明存在漏洞。

這里的難點(diǎn)在于對(duì)各種函數(shù)的調(diào)用,新手容易找不到調(diào)試思路,想要突破這個(gè)難點(diǎn)首先要熟悉URL路由、構(gòu)造URL鏈接,再結(jié)合前面介紹的調(diào)試工具phpStorm+Xdebug去調(diào)試。

對(duì)于有經(jīng)驗(yàn)的讀者來(lái)說(shuō),常見(jiàn)的代碼審計(jì)方式有兩種。

(1)功能點(diǎn)審計(jì)

可以先對(duì)程序代碼結(jié)構(gòu)及功能邏輯進(jìn)行了解,通過(guò)代碼側(cè)觀察目錄結(jié)構(gòu),知道哪些是核心目錄,哪些是配置目錄,哪些是邏輯功能代碼,再結(jié)合該程序運(yùn)行時(shí)的如下各種功能進(jìn)行審計(jì)。

●個(gè)人中心(其中包含頭像上傳、密碼修改……)。

●登錄注冊(cè)(其中包含信息注冊(cè)、登錄驗(yàn)證……)。

●文本留言(其中包含留言管理、留言?xún)?nèi)容……)。

●文本搜索(其中包含模糊查詢(xún)、搜索拼接……)。

●消息發(fā)送(其中包含內(nèi)容發(fā)送、附件發(fā)送……)。

功能越多,安全問(wèn)題也可能越多。從正常研發(fā)的角度來(lái)講,每一種功能的設(shè)計(jì)都是根據(jù)每個(gè)公司產(chǎn)品部門(mén)的需求來(lái)進(jìn)行設(shè)定和調(diào)試的,外加部分用戶(hù)的反饋進(jìn)行修繕和版本更新。從攻擊者的角度來(lái)講,功能上的每一個(gè)交互點(diǎn),每一個(gè)傳輸過(guò)去的參數(shù),每一個(gè)交互過(guò)去的文本內(nèi)容都可能會(huì)帶來(lái)攻擊的可能。

比如對(duì)于ThinkPHP5(TP框架5.0版本),若沒(méi)有代碼審計(jì)經(jīng)驗(yàn)或者不去關(guān)注Think-PHP3版本與ThinkPHP5版本的更新?tīng)顟B(tài),那么就可能會(huì)錯(cuò)過(guò)assign方法和display方法中產(chǎn)生的漏洞。ThinkPHP5與ThinkPHP3相比,封裝得更強(qiáng)大,便利性更高,這樣就更容易出現(xiàn)意想不到的漏洞。

(2)全代碼通讀

全代碼通讀并非代碼全讀,屬于正向追蹤。所謂正向追蹤可以簡(jiǎn)單地理解為從源代碼的程序執(zhí)行入口開(kāi)始,逐一進(jìn)行功能點(diǎn)審計(jì),包括所用到的開(kāi)發(fā)框架、程序設(shè)計(jì)模式等。例如在審計(jì)框架級(jí)的程序時(shí),可以先找出開(kāi)發(fā)手冊(cè)熟悉一下,然后根據(jù)手冊(cè)挑出可控點(diǎn)函數(shù)并追蹤代碼,如可控參數(shù)帶入了哪個(gè)方法,調(diào)用了哪個(gè)函數(shù),一直追到此功能不能再持續(xù)跟進(jìn)下去或者跟進(jìn)到有漏洞點(diǎn)的位置。這樣做的好處是查找漏洞時(shí)覆蓋率高,容易追蹤,URL鏈接好構(gòu)造。采用全代碼通讀方法進(jìn)行代碼審計(jì),需要熟悉各種漏洞類(lèi)型原理以及常見(jiàn)函數(shù)可能造成的漏洞及利用技巧,最重要的是要有耐心。

一般功能點(diǎn)審計(jì)方式與全文通讀代碼審計(jì)方式是結(jié)合使用的,這樣可以使效率更高。

2.URL構(gòu)造

要想通過(guò)URL構(gòu)造過(guò)程訪(fǎng)問(wèn)到漏洞發(fā)生的位置,必須知曉URL路由映射原理。下面通過(guò)實(shí)例演示如何通過(guò)分析學(xué)會(huì)構(gòu)造漏洞URL??稍诖罱ōh(huán)境后隨便點(diǎn)擊程序的幾個(gè)鏈接,查看如下部分:

●目錄結(jié)構(gòu)

●目錄命名

●代碼分析

需要觀察是單入口文件模式還是多入口文件訪(fǎng)問(wèn)模式。知名的ThinkPHP就是單入口文件模式框架。

多入口文件模式,從字面意思來(lái)講就是通過(guò)多個(gè)入口文件訪(fǎng)問(wèn)不同的功能模塊,例如常見(jiàn)的鏈接http://localhost//login.php、http://localhost//artcle.php?id=123等。

單入口文件模式的鏈接類(lèi)型是http://localhost//index.php?m=artcle&a=index&id=123,就是在域名的后面總有一個(gè)index.php(或其他入口文件名),這個(gè)入口文件名可以在URL中通過(guò)配置隱藏。

我們?cè)趯徲?jì)單入口文件模式的程序時(shí),要先看一下入口文件的代碼,比如常見(jiàn)的入口文件index.php(或其他命名的入口文件),還要查看是否有入口過(guò)濾文件的調(diào)用?;趥€(gè)人的研發(fā)經(jīng)驗(yàn)和安全經(jīng)驗(yàn),筆者一般會(huì)看一下目錄結(jié)構(gòu),找到功能模塊目錄,結(jié)合目錄名和在運(yùn)行的程序中隨便點(diǎn)擊的幾個(gè)鏈接,就可以構(gòu)造URL,找到URL鏈接映射到的代碼段,比如URL地址里的某個(gè)目錄、文件名或參數(shù)對(duì)應(yīng)了代碼段里的哪些功能、變量或函數(shù)的使用等信息,基于這些信息去嘗試定位漏洞發(fā)生位置。當(dāng)然這時(shí)漏洞發(fā)生點(diǎn)在可通過(guò)URL鏈接直接訪(fǎng)問(wèn)到的自定義方法中,如果漏洞發(fā)生點(diǎn)存在于不可直接訪(fǎng)問(wèn)的類(lèi)、方法中,那么可尋找通過(guò)URL鏈接訪(fǎng)問(wèn)到的方法的代碼中,是否有可直接或間接調(diào)用這個(gè)漏洞發(fā)生點(diǎn)的代碼。

3.漏洞挖掘

要想發(fā)現(xiàn)漏洞,必須掌握漏洞產(chǎn)生的原理,本書(shū)在后面介紹每種類(lèi)型漏洞的時(shí)候做了詳細(xì)的講解與分析,比如,每一種漏洞類(lèi)型的產(chǎn)生原理是什么,產(chǎn)生漏洞威脅的函數(shù)有哪些,PHP配置文件中哪些不當(dāng)配置會(huì)造成安全隱患等問(wèn)題,并與案例結(jié)合進(jìn)行實(shí)戰(zhàn)解析。

了解了程序本身的缺陷,再結(jié)合系統(tǒng)缺陷(如命令執(zhí)行,上傳漏洞的解析漏洞,截?cái)鄦?wèn)題等),就可以嘗試對(duì)一些Web安全漏洞進(jìn)行審計(jì)分析了。后續(xù)也可以通過(guò)多瀏覽行業(yè)大佬的博客,參加線(xiàn)下的沙龍與安全會(huì)議,看一看小型分享圈(如知識(shí)星球)來(lái)學(xué)習(xí)各種審計(jì)分析技巧。

4.防御突破

防御突破是攻擊者喜歡挑戰(zhàn)的一件事情。對(duì)方總是喜歡不動(dòng)聲色地打開(kāi)你的“門(mén)鎖”,發(fā)現(xiàn)里面的各類(lèi)秘密。對(duì)于安全審計(jì)人員而言,就是站在攻擊者視角去思考和嘗試突破一些常用的防御代碼、通用防御模塊等,由此掌握一些代碼審計(jì)的方法和技巧。

對(duì)于防御方法的繞過(guò),比如XSS(跨站腳本攻擊漏洞,是一個(gè)針對(duì)Web前端的漏洞)主要利用了前端JavaScript腳本的配合進(jìn)行觸發(fā),比如開(kāi)發(fā)者過(guò)濾了所有on事件,你也可以通過(guò)編碼對(duì)o或者n進(jìn)行編碼來(lái)嘗試?yán)@過(guò)。關(guān)于繞過(guò)各種防御,可以通過(guò)在網(wǎng)上搜索引擎搜索關(guān)鍵詞,如“waf繞過(guò)”來(lái)學(xué)習(xí)各種知識(shí)與思路,通過(guò)此手段可以嘗試來(lái)提升自己的繞過(guò)手法。

5.構(gòu)造Payload

構(gòu)造Payload時(shí),需要具備一定的編程基礎(chǔ),要理解漏洞原理,還需要掌握程序中的轉(zhuǎn)碼、序列化、類(lèi)型轉(zhuǎn)換等。在構(gòu)造Payload時(shí),可以嘗試反著寫(xiě)代碼。比如,如果外部傳參的參數(shù)在程序中被編碼了,你的Payload就應(yīng)是解碼后的形式;如果提交的數(shù)據(jù)被序列化了,你的Payload就應(yīng)是反序列化后的形式。

從客戶(hù)端傳遞參數(shù)到漏洞發(fā)生點(diǎn),經(jīng)過(guò)了哪些防御?怎么被轉(zhuǎn)碼?如何處理類(lèi)型轉(zhuǎn)換?需要把這些內(nèi)容用流程圖畫(huà)出來(lái),首先在漏洞發(fā)生處明確輸出或執(zhí)行的代碼是怎么樣的,然后拿著這些最終執(zhí)行的代碼往前推,該轉(zhuǎn)碼時(shí)就轉(zhuǎn)碼,該反序列化時(shí)則反序列化,最終推到客戶(hù)端請(qǐng)求的參數(shù)值時(shí),Payload就構(gòu)造出來(lái)了。

主站蜘蛛池模板: 剑阁县| 长岭县| 荣昌县| 勃利县| 丹棱县| 阿荣旗| 藁城市| 北辰区| 珲春市| 平顶山市| 怀集县| 中超| 额敏县| 合阳县| 湖南省| 商水县| 双鸭山市| 漾濞| 库车县| 报价| 太湖县| 保亭| 阳泉市| 健康| 福安市| 两当县| 泾源县| 讷河市| 蒲江县| 清水县| 临西县| 万载县| 黄梅县| 化德县| 平罗县| 马公市| 双柏县| 铁岭市| 察隅县| 毕节市| 郧西县|