當前位置:
首頁 > 新聞 > 單次點擊實現遠程代碼執行:內容管理框架Drupal惡意圖片上傳漏洞利用鏈分析

單次點擊實現遠程代碼執行:內容管理框架Drupal惡意圖片上傳漏洞利用鏈分析

概述

最近,Drupal發布了一組針對7.x和8.x版本的關鍵補丁。在更新中,包含對一組漏洞的修復,這些漏洞是我們最初在參與針對該目標的漏洞激勵計劃時提交的。這些漏洞可以實現代碼執行,但前提條件是攻擊者必須首先將三個惡意「圖像」上傳至目標伺服器,並誘導經過身份驗證的站點管理員點擊精心設計的鏈接來實現代碼執行。這並不是一個順利的漏洞利用途徑,因此我們也沒有獲得TIP的獎項。但是,這些漏洞可以被別有用心的攻擊者用來發起有針對性的攻擊,因此我們將對這些漏洞進行詳細分析。下面是其中一個漏洞的演示視頻:

https://youtu.be/GT5LCO7D3SE

通過對兩個漏洞的組合利用,可以實現單次點擊後的代碼執行,這兩個漏洞分別是ZDI-19-130以及Sam Thomas發現的ZDI-19-291。通過在註冊用戶帳戶時上傳個人資料圖片,或者在評論中上傳圖像,可以輕鬆實現任意圖像上傳。當然,禁用用戶註冊和用戶評論的Drupal站點不容易受到這些攻擊媒介的影響,但我們還是建議這部分用戶將Drupal伺服器更新到最新版本。

ZDI-19-130是一個PHP反序列化漏洞,通過利用該漏洞,攻擊者可以獲取站點Admin許可權的遠程代碼執行。ZDI-19-291是一個持久的XSS漏洞,攻擊者可以利用該漏洞來強制向管理員發出惡意請求,從而觸發ZDI-19-130漏洞。

ZDI-19-130的漏洞利用原理,是基於Thomas今年早些時候在Black Hat上發表的演講(PDF),各位讀者可以閱讀該演講的白皮書,也可以在這裡觀看他在BSidesMCR上發表過的同一個Black Hat演講的視頻。在演講中,Thomas詳細介紹了他發現的一個新的載體,通過Phar壓縮包觸發PHP反序列化漏洞。實質上,PHP Phar壓縮包的元數據以PHP序列化對象的形式存儲。Phar壓縮包上的文件操作可以觸發存儲的元數據上的unserialization()(反序列化),最終可能導致代碼執行。

另一方面,ZDI-19-291是處理上傳文件名過程中與Perl兼容的正則表達式(PCRE)相關的漏洞。當用戶上傳文件時,Drupal使用PRCE對文件名進行修改,以避免名稱重複。在過去的8年中,包含PCRE漏洞的提交始終存在於代碼庫中,並且可能導致Drupal在多次上傳時刪除文件名的擴展名,從而允許攻擊者上傳任意HTML文件。

回顧:PHP對象注入起源

早在2009年,也就是iPhone 3GS發布的同一年,Stefan Esser(@i0n1c)就證明PHP反序列化過程容易受到對象注入的影響,並且可以通過類似於ROP的代碼重用技術(PDF)來進一步利用。後來,他創造了「面向屬性編程」(Property Oriented Programming)(PDF)這一術語。在演示之前,PHP對象反序列化漏洞主要都是拒絕服務漏洞,或者難以利用的內存損壞漏洞。

類似於ROP的首次亮相,POP鏈的構建需要手工進行,並且過程較為繁瑣,沒有太多的工具或文獻可以用來參考。我所知道的唯一參考資料,就是Johannes Dahse等人在2014年發布的關於自動化POP鏈生成的優秀文章(PDF)。但遺憾的是,他們從未對外向公眾們發布過他們的工具。

回顧:POP漏洞利用商品化

PHP Generic Gadget Chains(PHPGGC)在2017年7月發布了.PHP Generic Gadget Chain庫,它可以被認為類似於ysoserial Java反序列化漏洞Payload庫。隨著PHP框架和庫的普及,以及PHP自動載入功能的幫助,PHP反序列化漏洞的利用最終變得非常簡單。

漏洞利用:第一階段(ZDI-19-291)

我們使用下面的PHP代碼,來測試Drupal源代碼中的一部分。根據源代碼中的注釋,下面的代碼段嘗試分離文件名中ASCII控制字元的部分,這部分字元值小於0x20,並用下劃線「_」字元替換它們。「/u」模式修飾符使得PHP引擎將PCRE模式和主字元串視為使用了UTF-8編碼。據我們推測,該修飾符已經被添加到PCRE模式中,從而確保與UTF-8的兼容性。

大家普遍會認為,UTF-8字元具有兩個位元組的長度。但與之相反,有效的UTF-8代碼點可能是1-4個位元組長度。UTF-8旨在向後兼容ASCII字符集。因此,在單位元組代碼點範圍內,ASCII(8位位元組0x00到0x7F)和UTF-8定義存在交集。0x80到0xF4之間的八位位元組用於多位元組UTF-8代碼點編碼。根據RFC3629中的標準,C0、C1、F5到FF的八位位元組值永遠不會出現在有效的UTF-8字元串中。

漏洞利用:第一階段(測試)

如果xFF位元組無效,並且x80位元組沒有有效的前導位元組,那麼PHP將會拋出PREG_BAD_UTF8_ERROR錯誤,並且每個文檔的$basename變數都將設置為NULL。

在Drupal源代碼中,在preg_replace()調用之後,不執行任何錯誤檢查。當包含無效UTF-8字元文件名的圖像兩次上傳至Drupal時,該函數將會運行,並將$basename變數鬆散地視為空字元串。最後,函數返回$destination,它被有效地設置為』_』.$counter 的結果。

有了這個原語之後,攻擊者可以通過用戶註冊功能,將GIF格式的個人資料圖片上傳至Drupal站點,並導致其擴展名被刪除。Drupal現在將會使用如下路徑和文件名:

/sites/default/files/pictures//_0

來替換:

/sites/default/files/pictures//profile_pic.gif

儘管對上傳的個人資料圖片進行了檢查,但在帶有「.gif」擴展名的HTML文件中添加字元「GIF」,即可滿足通過該檢查所需的要求。

同時,還有另一種方法能夠上傳惡意GIF文件,就是評論編輯器。在這種情況下,圖像將在/sites/default/files/inline-images/_0中提供。然而,在默認Drupal配置的情況下,攻擊者需要在評論的帖子發表之前註冊用戶帳戶。

當上述惡意行為,與通常在沒有任何Content-Type標頭的情況下提供圖像的事實相結合後,攻擊者可以將惡意GIF/HTML文件上傳到Drupal伺服器,並欺騙瀏覽器將惡意文件作為HTML網頁呈現,具體方法是將它們與內容類型提示相鏈接。示例如下:

總而言之,攻擊者可以在目標Drupal站點上實現持久性XSS。攻擊者可能利用該漏洞,強制具有管理員許可權的用戶通過誘使登錄用戶訪問惡意鏈接的方式,來實現第二階段的惡意查詢。在這裡可以找到可執行的PoC。

漏洞利用:第二階段(ZDI-19-130)

ZDI-19-130漏洞是通過位於/admin/config/media/file-system端點的file_temporary_path請求參數觸發的反序列化漏洞。攻擊者可以指定phar://流包裝器(Wrapper)將file_temporary_path參數指向在攻擊之前上傳到Drupal伺服器的惡意Phar壓縮包。

下面的system_check_directory()函數,是處理請求的表單回調函數。根據Thomas的演示,文件操作!is_dir($directory)足以導致PHP觸發在Phar壓縮包中的元數據的反序列化。通過POP鏈漏洞利用技術,攻擊者可以使用精心設計的Phar壓縮包,在Web伺服器的環境中執行任意代碼。

漏洞利用:第二階段(多語言)

在利用ZDI-19-130之前,我們必須將Phar壓縮包上傳到目標。具體而言,這可以通過在用戶註冊期間上傳JPEG/Phar多語言文件作為用戶個人資料圖片來實現。下面是一個PoC的JPEG/Phar多語言文件,當它與ZDI-19-130漏洞利用共同使用時,將會在受害者主機上執行cat /etc/passwd命令。

與JAR文件非常相似,Phar壓縮包是將各種組件打包到單個壓縮包文件中的集合。在PHP規範中,規定可以使用不同的壓縮包格式來打包組件。在具體的漏洞利用中,我們使用基於TAR的Phar壓縮包。

要創建多語言文件,攻擊者必須首先選擇JPEG圖像向量。然後,基於TAR的Phar壓縮包完整存儲在靠近JPEG文件開頭的JPEG注釋段中。當解析為TAR存檔時,圖像開始部分的JPEG段標記和注釋段標記將導致第一個文件名的略微損壞。當對TAR文件進行校驗並且修復時,一旦存儲在TAR/Phar壓縮包的第一個文件與包含POP鏈Payload的Phar元數據組件文件不對應,這種輕微的損壞對於漏洞利用的實際所需功能來說是無關緊要的。

漏洞組合利用

我們回顧一下,攻擊者必須首先將ZDI-19-130 JPEG/Phar多語言圖像文件上傳到目標伺服器,並確定上傳圖像的位置。然後,攻擊者必須兩次上傳ZDI-19-291 GIF/HTML圖像XSS,以使得圖像以沒有擴展名的文件名形式存儲在伺服器上。最後,攻擊者必須誘使網站管理員通過具有適當內容類型提示的鏈接,導航到目標伺服器上託管的ZDI-19-291 GIF/HTML圖像,以使瀏覽器將圖像呈現為HTML頁面,並觸發漏洞的第二部分。如果一切順利,攻擊者將能夠實現Web伺服器上代碼執行,並將得到反向Shell,如上面的演示視頻所示。

總結

Thomas提出了一種新穎的攻擊載體,可以為攻擊者打開許多新的大門。除非PHP決定修改Phar壓縮包處理行為,否則程序員在通過文件操作符傳遞用戶控制的數據時,需要格外警惕。由於將用戶控制的數據傳遞到無害的文件操作符(例如:is_dir())並不會被視為高風險的操作,我們預計,後續將會出現更多利用此向量的漏洞。隨著POP鏈漏洞利用工具集的推進,PHP反序列化漏洞將變得能被攻擊者輕鬆利用。軟體提供商應該將這一現狀視為serialize()的最後一根稻草,並應該立即著手換用更安全的json_encode()替代方案。

儘管我沒有得到TIP的最終獎項,但在整個研究過程中我還是發現了嚴重的漏洞,並以非常投入的狀態進行了深入分析。如果各位讀者對TIP計劃感興趣,請關注我們的博客,這一系列活動的總獎金超過1000000美元,大家可能會發現一些非常值得關注的漏洞潛在領域。

大家可以在Twitter上找到我@TrendyTofu,同時也可以關注團隊,以獲取最新的漏洞利用技術和安全補丁。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 嘶吼RoarTalk 的精彩文章:

淺談等級保護測評
黑客通過入侵客戶支持系統 訪問Outlook郵箱讀取用戶信息

TAG:嘶吼RoarTalk |