安全文库

【技術分享】手把手教你如何完成Ruby ERB模板注入


【技術分享】手把手教你如何完成Ruby ERB模板注入

2017-09-18 14:34:45 閱讀:6770次 點贊(0) 收藏 來源: trustedsec.com

作者:興趣使然的小胃


【技術分享】手把手教你如何完成Ruby ERB模板注入

譯者:興趣使然的小胃

預估稿費:200RMB

投稿方式:發送郵件至linwei#360.cn,或登陸網頁版在線投稿


前言:現在Web應用的模板


現在的Web應用中,許多客戶端以及服務器端經常會用到模板。許多模板引擎提供了多種不同的編程語言實現,比如Smarty、Mako、Jinja2、Jade、Velocity、Freemaker以及Twig等模板。作為注入攻擊大家族中的一員,模板注入這種攻擊形式對不同的目標所造成的影響也有所不同。對於AngularJS而言,模板注入攻擊可以達到XSS攻擊效果,對於服務器端的注入攻擊而言,模板注入攻擊可以達到遠程代碼執行效果。

作為大名鼎鼎BurpSuite工具的開發商,Portswigger寫了一篇文章詳細介紹了服務器端的模板注入攻擊。對攻擊者而言,首先需要做的就是識別模板引擎、枚舉可訪問的類或方法,最終利用這些信息完成預期的操作,比如讀取或寫入文件、命令執行或其他操作等。攻擊者具體能執行哪些操作取決於可訪問的類方法或函數的能力範圍。


模板攻擊:Ruby/ERB模板注入


在本文中,我們會使用TrustedSec應用安全課程中的實驗目標,演練一遍Ruby/ERB模板注入攻擊。我們的實驗對象是一個簡單的應用,該應用可以模擬包含模板編輯功能的一種IT服務台(Helpdesk)報告工具。我們可以通過這個應用來編輯HTML及模板,也可以預覽編輯效果,如下圖所示:

【技術分享】手把手教你如何完成Ruby ERB模板注入【技術分享】手把手教你如何完成Ruby ERB模板注入

使用預覽(preview)按鈕提交表格后,呈現在我們眼前是包含用戶信息以及用戶創建時間的一個頁面:

【技術分享】手把手教你如何完成Ruby ERB模板注入【技術分享】手把手教你如何完成Ruby ERB模板注入

觀察代碼中獲取username以及tombstone時所使用的語法,根據其中的<%=語法以及其他一些Ruby技術,我們可以猜測這段代碼屬於Ruby/ERB代碼。基於這個判斷,我們可以編輯輸入數據,測試我們是否可以進行模板注入。大致瀏覽ERB文檔后,我們了解到<%=語法可以用來執行Ruby語句,並會嘗試將結果轉換為字符串,以附在最終的結果文本中。我們可以使用如下攻擊載荷來嘗試執行數學運算:

ruby <%= 7 * 7 %>

運算結果為49,每個用戶都會打印一次運算結果,如下所示:

【技術分享】手把手教你如何完成Ruby ERB模板注入【技術分享】手把手教你如何完成Ruby ERB模板注入

可以肯定的是,這段代碼存在模板注入漏洞。非常好,接下來我們可以試試看能否執行函數。我們可以先來測試自帶的全局函數是否能用到這段代碼中。比如,我們可以測試如下這種載荷:

ruby <%= File.open(‘/etc/passwd’).read %>

【技術分享】手把手教你如何完成Ruby ERB模板注入【技術分享】手把手教你如何完成Ruby ERB模板注入

由於不安全操作的原因,系統阻止我們訪問File.open函數。Ruby的ERB模板引擎包含一個安全級別(safe level)參數,當安全級別設置為0以上的某個值(比如3)時,我們無法在模板綁定(template binding)中執行包括文件操作在內的某些函數。如果應用使用的安全級別為4,那麼它會使用最為嚴格的隔離機制,只能執行標記為可信狀態的那些代碼。因此,看樣子管理員在這個模板引擎中設置了安全級別。雖然我們的攻擊不會像讀寫硬盤文件那樣簡單,但這裡我們還可以嘗試許多攻擊面。比如,對於目前可用的這些小工具(gadget),我們還可以做什麼操作?如果我們想分析self對象(self-object),我們可以嘗試枚舉該對象可用的屬性及方法。比如,我們可以使用如下載荷:

ruby <%= self %>

結果如下:

【技術分享】手把手教你如何完成Ruby ERB模板注入【技術分享】手把手教你如何完成Ruby ERB模板注入

結果看起來就是Ruby的風格。現在我們可以試着獲取self對象的類名:

ruby <%= self.class.name %>

結果如下:

【技術分享】手把手教你如何完成Ruby ERB模板注入【技術分享】手把手教你如何完成Ruby ERB模板注入

類名為“TemplateInjection”。現在我們已經可以“訪問”這個控制接口,我們能用它來幹啥?我們可以來枚舉TemplateInjection類的可用方法:

ruby <%= self.methods %>

結果如下:

【技術分享】手把手教你如何完成Ruby ERB模板注入【技術分享】手把手教你如何完成Ruby ERB模板注入

接下來,我們可以觀察這些函數,思考哪些數據可以傳遞給這些函數,以實現未授權訪問目的。雖然我們並不清楚該應用具體使用的web框架,但由於我們正往服務器發送HTTP POST請求,因此可以猜到我們很有可能處於handlePOST或者doPOST函數內部。也許我們可以藉此訪問某些局部變量。

如果大家不熟悉Ruby,這裡我稍微介紹下。Ruby提供了強大的元編程(metaprogramming)以及內省(introspection)功能,讀者可以訪問此鏈接了解更多細節。作為攻擊者,我們可以使用其中某些功能(如前面提到的類的.methods以及.name方法)來探索程序的內部結構。我們可以使用如下載荷獲取目標所需的具體參數:

ruby <%= self.method(:handle_POST).parameters %>

結果如下:

【技術分享】手把手教你如何完成Ruby ERB模板注入【技術分享】手把手教你如何完成Ruby ERB模板注入

從結果中,我們可知handle_POST需要3個req參數,該參數可能代表的是某個請求(request)對象;rsp參數可能代表的是響應數據的引用;最後的session參數可能是某個id或者某個對象。我們可以繼續探索,以確認session對象的具體含義,使用的載荷如下:

ruby <%= session.class.name %>

結果如下:

【技術分享】手把手教你如何完成Ruby ERB模板注入【技術分享】手把手教你如何完成Ruby ERB模板注入

上述結果中,我們首先可以觀察到的是“WEBrick”,這是Ruby在標準庫中實現的原生web服務器。我們當然可以繼續探索這個session對象,但除此之外,還有其他一些目標更值得我們探索,比如,我們可以重點關注與當前會話有關的那些數據。簡單翻閱WEBrick文檔后,我們發現某些變量會傳遞給Servlet以處理客戶端請求。我們可以使用某些內省(introspection)方法,以確認我們是否可以訪問這些變量以及其他可用變量。

ruby <%= self.instance_variables %>

結果如下:

【技術分享】手把手教你如何完成Ruby ERB模板注入【技術分享】手把手教你如何完成Ruby ERB模板注入

當WEBrick被實例化以處理客戶端請求時,它會將某個http服務器實例傳遞給servlet,這很有可能就是@server這個實例變量。接下來我們可以證實這個猜想,同時觀察這個對象包含哪些成員變量。我們同樣可以通過調用.instance_variables方法來證實這一點:

ruby <%=@server.instance_variables %>

結果如下:

【技術分享】手把手教你如何完成Ruby ERB模板注入【技術分享】手把手教你如何完成Ruby ERB模板注入

其中最為有趣的應該就是@ssl_context變量。這個變量可能會包含某些密鑰或者其他有用的信息。需要注意的是,接下來我們會稍微改一下語法,使用<%來執行Ruby語句。通過這種語法,我們可以創建自己的局部變量,保存@sll_context的引用,使載荷可讀性更好,方便隨後在模板中加以引用。

ruby <% ssl=@server.instance_variable_get(:@ssl_context) %><%= ssl.instance_variables %>

結果如下:

【技術分享】手把手教你如何完成Ruby ERB模板注入【技術分享】手把手教你如何完成Ruby ERB模板注入

結果中,@key看起來非常有趣,我們可以提取這個值:

ruby <% ssl = @server.instance_variable_get(:@ssl_context) %><%= ssl.instance_variable_get(:@key) %>

結果如下:

【技術分享】手把手教你如何完成Ruby ERB模板注入【技術分享】手把手教你如何完成Ruby ERB模板注入


總結:風險與檢驗


在實際生活中,服務器私鑰被泄露是非常嚴重的一件事情。作為應用安全測試員,我們的測試操作到此差不多就該停止了。開發人員可以採用多種方式來限制數據的讀取範圍,進一步沙箱化模板中運行的代碼。我們會根據測試過程中對目標應用的了解來給出相應的建議。作為應用測試人員,我們需要全方位探索哪些模板代碼會提交到服務端進行處理。雖然存在一定的安全風險,但是由用戶提供模板的場景依然非常常見,特別是在某些應用中更是如此(比如用來生成報表以及發送郵件的那些應用)。希望讀完這篇文章后,讀者可以掌握一定的技巧來測試現在常用的那些模板引擎。


【技術分享】手把手教你如何完成Ruby ERB模板注入 【技術分享】手把手教你如何完成Ruby ERB模板注入

本文由 安全客 翻譯,轉載請註明“轉自安全客”,並附上鏈接。
原文鏈接:https://www.trustedsec.com/2017/09/rubyerb-template-injection/