前言#
這篇文章是今年 USENIX 一篇關於 php debloating 文章的前置文章(被簡稱為 LIM,Less is More)
profiles:配置,情境;profilling:分析(性能分析、行為分析等);profiler:分析器
bloat:膨脹;debloat:去膨脹
ambient authority: 環境權限是系統訪問控制研究中的術語。當主體指明它需要的客體的名稱和它將要對該客體執行的動作便可以完成該動作的時候,我們稱該主體使用了環境權限。
monkey testing: 猴子測試是一種用戶通過提供隨機輸入並檢查行為或查看應用程序或系統是否崩潰來測試應用程序或系統的技術。Monkey 測試通常作為隨機的自動化單元測試來實現。
Overview of paper#
文章利用動態分析獲取 php web 應用的代碼覆蓋情況,並把未使用的代碼刪除,來達到去膨脹的目的
概括一下,大致有以下幾個部分:
- 挑選 CVE 漏洞並映射到 web app 中
- 挑選了四組不同的用戶集,並對 app 的使用進行模擬
- 記錄代碼覆蓋率並分析未使用的文件 / 函數
- 根據覆蓋情況進行 debloat 並得到 debloated app(主要有文件級 debloating 和函數級 debloating)
- 對 debloated 的 app 進行正常的使用模擬,評估功能是否仍然正常
- 把 debloated 的 app 和原始 app 同時進行已知 CVE 的 exploit,評估 debloating 的效果(即 debloating 是否刪除了導致漏洞的關鍵代碼),以及其它各類的評估和對比
這裡配了個 Figure 1,裡面有一個錯別字 Expoits
background#
軟件 debloating 的原理已在操作系統(從 Linux 內核中刪除不必要的代碼)、共享庫和編譯的二進制應用程序上成功過
本文中第一次提出了在 web app 上評估 debloating 的適用性,看看能否刪除導致漏洞的關鍵代碼
web debloating 的 motivation#
作者用了 Symfony 的 CVE-2018-14773 來講述
該框架支持一個遺留的 IIS 標頭,可能導致濫用。如果服務器不需要使用該標頭,則可以從中刪掉相關對其支持的代碼,即 debloating
目標 php web app#
- phpmyadmin:數據庫管理
- wordpress:博客管理
- mediawiki:維基管理
- magento:電商管理
漏洞映射至源码#
每個 web app 根據 CVSS 評分挑選了 20 個最 critical 的 CVE,且全部是 2013 年及其後的 CVE
由於不同 CVE 的影響版本不同,為了應用所有這些 CVE,不得不跨多個版本映射漏洞(如下表)
每個 CVE 所影響的版本和行號都記錄在了數據庫中
Web Application | Version | Known CVEs(≥2013) |
---|---|---|
Magento | 1.9.0, 2.0.5 | 10 |
MediaWiki | 1.19.1, 1.21.1, 1.24.0, 1.28.0 | 111 |
phpMyAdmin | 4.0.0, 4.4.0, 4.6.0, 4.7.0 | 130 |
WordPress | 3.9.0, 4.0, 4.2.3, 4.6, 4.7, 4.7.1 | 131 |
web app 使用模擬#
有如下四種方法模擬 app 的使用,以達到盡可能廣和深的功能覆蓋率,或者說代碼覆蓋率
- 一般教程(用 selenium 腳本執行)
- monkey testing
- 爬蟲
- 漏掃
記錄 web app 代碼覆蓋率#
php 分析器作為 php 擴展提供,原理是修改 php 引擎來收集代碼覆蓋率,文中使用的是 XDebug
直接的想法是將xdebug_start_code_coverage()
和xdebug_get_code_coverage()
添加到每一個 php 文件的末尾,但是作者遇到了一些困難
由於任意 php 文件都可以提前調用exit()
或die()
來提前退出,故需要把上面兩個記錄函數加在退出函數之前
其次,還需要註冊 shutdown 函數,並把其添加到 shutdown 函數隊列的末端
最後是析構函數,如果類在 shutdown 函數之後被銷毀,則這部分 cover 不到,故重寫了析構函數使得它們在執行時註冊自己
Debloating 策略#
- 文件級 debloat:刪掉沒有執行的 php 文件
- 函數級 debloat:比文件級更細粒度的 debloat,可以刪除函數中未執行的代碼塊
這裡的 debloating 並不是完全把代碼刪除,而是替換成佔位符,如果代碼執行到這些佔位符,則程序會退出,並記錄相關缺失函數的信息
後續證明這種方法非常有效,記錄了很多不應該刪除的 file/function
實驗結果#
衡量代碼數量的標準不是單純的代碼行數,而是 Logical Lines Of Code(LLOC),其不計入註釋、空行、必要語法結構等行數
顯然,函數級 debloating 比文件級 debloating 所減少的代碼要多,當然也和這四個不同項目的代碼實踐風格有關(比如 wordpress 就不那麼依賴外部 package,比如 magento 和 mediawiki 是以更加模塊化的方式開發的)
- 圈複雜度的減少
圈複雜度(Cyclomatic complexity,CC)也稱為條件複雜度,其數量上表現為獨立路徑的條數,也可理解為覆蓋所有的可能情況最少使用的測試用例個數
發現大三的軟件工程課學過這個概念
在 debloat 過程中,圈複雜度也有降低,說明應用的 debloat 方法能夠刪除複雜的指令和執行路徑
- debloating 後 CVEs 的減少
結果發現 38% 的漏洞能通過文件級 debloating 刪除,10%~60% 是通過函數級 debloating 刪除的(有大量外部庫的 phpmyadmin&magento 與較為單一的 wordpress 是兩個極端)
注意:這裡本文所認為漏洞是否被 debloat 掉的規則是,原本某個漏洞利用所 cover 的所有 file/function 全部被刪除,而不是僅刪掉其中一個環節(雖然大部分情況這樣已經破壞了利用鏈而導致漏洞實際上不能利用了)
這一部分我覺得作者關於 debloating 是如何基於前面四種場景進行的具體規則,並沒有說的很明白
因為有兩種情況,一種是正常使用,其不會觸發漏洞(如 tutorial),而另一種是刻意進行漏洞利用(如漏掃)或者導致應用進入異常情況,而 monkey testing 同時會產生兩種情況
我暫且認為基於以下的規則進行 debloating:
- 在保證程序正常運行的基礎上進行,即在功能性和會導致漏洞的可能性衝突中給功能性讓步
- 被正常使用所 cover 的 file/function 之外的代碼要刪除
- 若惡意利用 cover 的路徑和正常使用 cover 的路徑有部分重疊,那麼非重疊部分就被刪除,重疊部分滿足第一條的規則要求而保留
其實說白了就是正常使用所 cover 之外的代碼需要刪除
- 不同漏洞類型的影響
不同的漏洞類型的 debloat 程度也不同,比如命令執行,SQL 注入等漏洞容易被 debloat(常常存在於不常用的模塊中),而 crypto,cookie 相關的漏洞則不容易被 debloat(常存在於主要的加密函數中,屬核心組件不能刪除)
- POI 漏洞的檢查
POI,即 PHP Object Injection,在 CTF 裡面其實就是 PHP 反序列化漏洞
作者使用了 PHPGGC,一個生成 POP 利用鏈的工具來進行對 debloated app 的 exploit
結果顯示函數級 debloating 成功移除了所有 PHPGGC 中存在的利用鏈所對應的漏洞(wordpress 不在此列中,因為 wordpress 不依賴於外部軟件包)
- dev 包的不當引入
composer 默認將外部軟件放在 vendor 目錄下,如果該目錄恰好能通過服務器的錯誤配置而訪問,則可能可以被利用來進行 RCE(比如 PHPUnit)
實驗結果表明 phpmyadmin 和 magento 存在此問題
- 對刪除的代碼的定性分析
由於刪除的文件和代碼過多,本文使用的是 k-means 聚類算法來產生文件分組,並使用 TFIDF 最大頻率限制來忽略出現在超過 50% 的文件路徑中的共同部分
- 對 debloated app 進行 exploit 測試
最後作者收集了 metasploit 框架中存在的針對這四個 php web app 的 CVE,並根據公開漏洞信息把他們編寫成了 POC
在驗證原始版本的 web app 都能夠被利用成功後,對 debloated 版本進行測試,有一半失敗(4 of 8)
此結果說明 debloating 對於 web app 的安全方面雖然不是萬能的,但是是有效的
性能分析#
由於代碼覆蓋工具會對性能增加開銷,本節進行的討論是對 XDebug 工具的開銷分析,即 selenium 腳本在有 XDebug 和沒有時進行對比
結果顯示,四種 web app 的開銷在執行時間、CPU 消耗、內存消耗都有提升
但是這種開銷是可以通過改進覆蓋率計算方式來降低的,比如覆蓋率以離線方式計算等,這部分工作留到以後討論
局限性和未來工作#
對前面的工作總結一下,即 debloating 能減少數十萬行無關代碼,減少圈複雜度 30%~50%,刪除約一半與 CVE 相關的導致漏洞的代碼,即使對於不能刪除的漏洞,debloating 也能刪除一些 gadgets 使其變得更難利用
文章作者認為本文的工作尚不完善,仍有以下局限
- 缺乏可利用漏洞
缺乏公開可利用的漏洞,包括各類漏洞利用復現、細節說明等
其中作者還提到了缺少針對 web app 的自動利用腳本(比如 BugBox),因為這樣可以大大幫助研究人員的工作
- 動態代碼覆蓋
web debloating 大大依賴於動態代碼覆蓋分析,且即使有四種可複製且無偏見的應用使用配置場景,也仍不能聲稱其覆蓋了 web app 的所有良性狀態
說白了是覆蓋的深度不夠,作者打算通過眾包(crowd sourcing)和用戶研究(user studies)來跟進
其次,由於該 pipeline 是對於指定的用戶集來刪除不需要的功能,故不能進行一般的靜態分析工作,但是作者提出可以在 debloating 之後的代碼基礎上進行一個靜態分析的工作,來確保對於這些用戶集來說其需要的功能是仍然存在的
- 處理流向被刪除代碼的請求
當真實用戶有請求到被刪除代碼時,如何進行處理?僅退出應用並返回錯誤是不夠的,應該重新引入那些被刪除的代碼並處理用戶的請求,且在這之前需要確定是否該請求是惡意的
- 衡量 debloating 有效性的指標
本文使用圈複雜度減少、邏輯代碼行(LLOC)減少、CVE 減少和 POP 鏈這四個指標減少來衡量其有效性
但是每一行代碼對程序的攻擊面的貢獻都是不同的,同時 CVE 的標準也不適用於專有軟件,且 CVE 還需要手動映射才能驗證可利用性,工作量巨大
- debloating 的效率
模塊化應用的 debloating 效率明顯由於單體應用(如 wordpress)
相關工作#
這裡作者提到了不少靜態分析的 debloating 工作,以及 web 客戶端的 debloating 工作(減少 chrome 的攻擊面),以及一個動態分析自定義 php web 應用的工作(此工作局限性是不能定量確定減少的漏洞數量,因為是自定義的)
總結#
由於我自己的想法總結已經寫在前面的 Overview of paper 了,這裡就貼上原文的 abstract 和 conclusion 吧
Abstract
隨著軟件變得越來越複雜,其攻擊面擴展使得各種漏洞的利用成為可能。Web 應用程序也不例外,因為現代 HTML5 標準和不斷增強的 JavaScript 能力被用來構建豐富的 web 應用程序,常常取代傳統桌面應用程序的需求。處理這種增加的複雜性的一種可能方法是通過軟件 debloating 過程,即不僅刪除死代碼,還刪除對特定用戶集不需要的功能所對應的代碼。儘管 debloating 已成功應用於操作系統、庫和編譯程序,但其在 web 應用程序上的適用性尚未被調查。在本文中,我們呈現了對 web 應用程序 debloating 安全益處的首次分析。我們專注於四個流行的 PHP 應用程序,並動態地對其進行測試,以獲取由客戶端請求觸發的服務器端代碼的信息。我們評估了兩種不同的 debloating 策略(文件級 debloating 和函數級 debloating),並顯示我們可以生成功能性 web 應用程序,其大小比原始版本小 46%,並顯示出其原始圈複雜度的一半。此外,我們的結果顯示,debloating 過程刪除了與數十個歷史漏洞相關的代碼,並通過刪除不必要的外部包和可濫用的 PHP gadgets 進一步縮小了 web 應用程序的攻擊面。
Conclusion
在本文中,我們分析了通過一個稱為軟件 debloating 的過程刪除現代 web 應用程序中不必要代碼的影響。我們呈現了我們設計和實施的端到端模塊化 debloating 框架的管道細節,使我們能夠記錄 PHP 應用程序的使用情況以及由客戶端請求觸發的服務器端代碼。在檢索代碼覆蓋信息後,我們的 debloating 框架使用文件級和函數級 debloating 刪除應用程序的未使用部分。通過在四個流行的 PHP 應用程序(phpMyAdmin、MediaWiki、Magento 和 WordPress)上評估我們的框架,我們見證了 debloating web 應用程序的明顯安全益處。我們觀察到 LLOC 顯著減少,文件級 debloating 範圍在 9% 到 64% 之間,函數級 debloating 則額外減少了最多 24%。接下來,我們顯示外部包是膨脹的主要來源之一,因為我們的 debloating 框架能夠刪除使用 Composer 的版本中超過 84% 的未使用代碼。通過量化與關鍵 CVE 相關的代碼的刪除,我們觀察到高達 60% 的高影響歷史漏洞的減少。最後,我們顯示 debloating 過程還刪除了指令和類,這些是攻擊者構建 gadgets 和執行 POI 攻擊的主要來源。我們的結果表明,debloating web 應用程序提供了切實的安全益處,因此應被認真考慮作為減少 web 應用程序部署攻擊面的一種實用方法。