Kate Li (Taiwan)的部落格

首頁

rails xml參數解析漏洞分析-影射器.net

作者 iacona 時間 2020-04-10
all

本文試圖概述今天修補的新Rails XML參數解析漏洞的背景和影響。

蟲子

該漏洞的根本原因是Rails處理格式化參數。除了標準的GET和POST參數格式外,Rails還可以處理POST請求主體中的多個不同數據編碼。默認情况下支持JSON和XML。雖然JSON的支持在生產中被廣泛使用,但是許多Rails開發人員似乎並不知道XML功能。

XML參數解析

負責分析這些不同資料類型的程式碼如下所示:

幸運的是,Proc和:yaml案例在默認情况下是不可訪問的,JSON也不重要,但是XML案例調用Hash.from_XML(),將原始POST體作為參數傳遞。下麵的程式碼是一個簡化的程式碼,僅顯示此程式碼路徑的相關部分。

類型化XML

可以看到,程式碼支持將XML樹反序列化為不同的資料類型。雖然基本類型(如數組、字串和散列)可以很容易地處理,但是XML解析器還包括對其他幾種類型的額外支持,以便正確地解析下麵程式碼片段之類的程式碼。

這種類型支持有助於不希望實現自己的日期或整數解析程式碼的應用程序。它使用“type”内容和以下程式碼行實現:

不幸的是,ActiveSupport::XmlMini::PARSING不僅包括像整數或浮點數這樣無害的類型,而且還包括兩種具有重要安全影響的特殊類型:symbol和yaml。

符號和軌道

符號是一種特殊的ruby類型,通常使用:name語法創建。符號有幾個有趣的内容,這些内容超出了本文的討論範圍,但最重要的是,內部Rails函數依賴於這樣一個假設,即沒有外部用戶可以向符號注入惡意值。這一假設已經在幾個方面受到攻擊,最近一次是約一個月前joernchen在CVE-2012-5664中提出的。即使使用了coressponding補丁,也可能存在更多使用惡意符號的攻擊向量。對於此錯誤,由於在parse_格式化的_參數中調用data.with_indater_access會將雜湊表中的所有符號鍵轉換為字串,這使得對CVE-2012-5664的利用更加困難,囙此减少了影響。但該病媒仍然存在,開發利用仍有可能。

最後,符號的注入是一個嚴重的安全問題。第二種類型的“yaml”更有趣。

山藥

YAML(YAML不是標記語言)是一種類似於JSON的數據序列化格式。在ActiveSupport::XmlMini::Parsing中使用以下條目實現對XML內部YAML的支持:

您可能還記得,由於YAML(或者更具體地說,大多數指令碼語言(如Python或Ruby)使用的YAML解析器沒有被設計為處理惡意用戶輸入,囙此Rails默認情况下不啟用YAML格式的參數。Ruby使用的YAML解析器支持任意資料類型的序列化和反序列化。這包括符號(再次!)還有任意對象。YAML字串“-!ruby/object:A\foo:1\n bar:1\n“將創建類A的對象實例,並將對象内容@foo和@bar設定為值1。這意味著攻擊者可以創建目標Rails應用程序中定義的所有類的實例。這包括基本的ruby類,在不同的activexy名稱空間中定義的所有類,甚至包括像rack這樣的低級庫使用的類。這將打開一個巨大的攻擊面,如下一節所述。

對象注入攻擊

囙此,我們可以將任意對象實例作為參數插入正在運行的Rails應用程序。有什麼影響?讓我們看看其他的網絡堆棧:

菲律賓比索

PHP中的對象注入可以使用Stefan Esser在2009年描述的unserialize()函數。由於像wakeup和destruct這樣的“神奇方法”可以在反序列化或垃圾收集對象時獲得calledevery,囙此命令可以在大多數非平凡的和當前的PHP應用程序中執行,如phpMyAdmin、Typo3、Piwik或CakePHP中的錯誤所示。

爪哇

Johannes Dahse在Apache Struts2 web框架中發現了一個非常類似的漏洞,總結了非常詳細的博客文章:遠程命令執行是可能的。

蟒蛇

最後,python使用的pickle庫很容易被攻擊,因為它包含序列化數據格式的類定義,如Nelson Elhage在本文中所示。

正如這些示例所示,對象注入漏洞可以通過多種不同的管道被利用。在下一節中,我們將展示Rails應用程序的一些潜在攻擊向量

鐵路開發

讓我們回顧一下攻擊者由於所描述的YAML注入而獲得的能力:他可以創建應用程序中定義的任何類的對象實例。此外,他可以將所有實例變數設定為任意值,並且不受initialize或setter方法中validatios的限制。

想像一下上面的(相當愚蠢的)示例類B,如果我們能够對反序列化對象調用foo()方法,我們就可以執行任意程式碼。例如YAML字串“-!ruby/object:B\ncode:puts 10\n“會導致puts 10的執行。當然,大多數實際應用程序都沒有這樣簡單的利用向量,但是由於ruby的强大功能,Rails成為了一個簡單的目標:

Ruby確實有一個動態類型系統和對運算子重載的豐富支持。缺少類型檢查,並且假設所有用戶傳遞的值都是字串、數組或雜湊值,這會打開許多攻擊向量。雖然我們確實發現了可用於注入任意程式碼的多個類和程式碼路徑,但在大多數網站應用修補程式之前,我們不會發佈有關它們的詳細資訊。相反,我們演示如何使用對象注入來使用arel對象對Rails 3應用程序執行SQL注入攻擊。

arel允許使用熟悉的ruby語法創建複雜的SQL査詢。對arel的深入討論超出了本文的討論範圍,但是當arel對象作為參數傳遞給一個Rails動態finder方法(find_by_*)時,它有一個有趣的内容:表示arel對象的SQL程式碼直接複製到finder方法創建的SELECT語句中,而不應用任何轉義:

這與CVE-2012-5664非常相似,在正常情况下不會有問題,但是因為我們可以使用YAML創建Arel::Nodes::SqlLiteral對象,所以當像這樣調用finder方法時,很容易利用它:

我們可以將表示對象的字串作為x參數的值傳遞到格式正確的XML post主體中。這將導致創建一個SqlLiteral對象,並在執行的SQL語句中注入“SQLCODE”。我們針對運行最新版本的redmine專案管理應用程序的Rails 3.2.10驗證了此攻擊,並可以作為未經驗證的用戶選取任意資料庫條目。請注意,動態查找器需求是特定於此攻擊向量的。即使沒有使用動態查找程式,任意程式碼注入仍然是可能的。

摘要

所討論的漏洞非常嚴重,允許在所有不禁用XML格式參數解析的Rails應用程序中執行程式碼和SQL注入。管理員應儘快應用已發佈的修補程式。如果無法及時更新ActionDispatch::ParamsParser::DEFAULT_,則應修改解析器以删除XML支持。

菲利克斯·威廉