漏洞描述
Apache Struts2在使用REST插件的情況下,攻擊者使用REST調(diào)用惡意表達式可以遠程執(zhí)行代碼。該漏洞編號為CVE-2016-4438,定名S2-037。該漏洞和S2-033漏洞觸發(fā)流程基本一致,都是在ActionMapping中methodName帶入到OGNL表達式中執(zhí)行,從而導(dǎo)致任意代碼執(zhí)行。
影響范圍
Struts 2.3.20 – Struts 2.3.28.1
所有安裝REST插件的Struts應(yīng)用
漏洞原理
在5月12日安恒報告的CVE-2016-3087(S2-033)中,若Struts2應(yīng)用安裝REST插件,且開啟DMI(Dynamic Method Invocation)動態(tài)方法調(diào)用,攻擊者可以注入惡意表達式造成遠程代碼執(zhí)行。官方補丁公告(https://cwiki.apache.org/confluence/display/WW/S2-033)中描述寫道:
Remote Code Execution can be performed when using REST Plugin with ! operator when Dynamic Method Invocation is enabled.
S2-033影響范圍為:
Struts 2.3.20 – Struts Struts 2.3.28 (except 2.3.20.3 and 2.3.24.3)
然而在官方修補該漏洞過程中,只是在DefaultActionMapper.java文件中加入了對method成員的值進行OGNL表達式過濾
https://github.com/apache/struts/blob/095960b5691d33f127000794b3e79638cf384652/core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java
然而在該漏洞觸發(fā)代碼中,還有另一個入口,于是導(dǎo)致了S2-037的發(fā)生
Struts2的rest插件在處理類似http://127.0.0.1:8080/chaitin/action-name/1/rr的URLs時,會查找名字以rr的方法調(diào)用,即actionname中的public String rr()會被調(diào)用
該處methodName沒有做過濾校驗,直接放入了mapping中,造成了代碼執(zhí)行
驗證PoC
驗證檢測:
http://127.0.0.1:8080/chaitin/memeda/rr/(%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS%29%3f(%23wr%3d%23context%5b%23parameters.obj%5b0%5d%5d.getWriter(),%23wr.println(%23parameters.content[0]),%23wr.flush(),%23wr.close()):xx.toString.json?&obj=com.opensymphony.xwork2.dispatcher.HttpServletResponse&content=vulntestbyrr
response中回顯vulntestbyrr即存在該漏洞
修復(fù)方案
加入cleanupActionName方法進行過濾
如同文中所述的S2-033中的修復(fù)方案,對method成員進行過濾,在mapping.setMethod(fullName.substring(lastSlashPos + 1));
該行加入cleanupActionName方法進行過濾即為 mapping.setMethod(cleanupActionName()fullName.substring(lastSlashPos + 1)));
根據(jù)官方漏洞公告和建議及時修復(fù)
官方公告https://cwiki.apache.org/confluence/display/WW/S2-037中的建議升級到2.3.29.
Upgrade to Apache Struts version 2.3.29.
作者 長亭科技