S2-012 远程代码执行漏洞检测与利用

前言

漏洞环境改自vulhub的,环境地址 https://github.com/kingkaki/Struts2-Vulenv/tree/master/S2-012

漏洞信息

https://cwiki.apache.org/confluence/display/WW/S2-012

当发生重定向时,OGNL表达式会进行二次评估,导致之前在S2-003S2-005S2-009进行的参数过滤未对重定向值进行过滤,导致了OGNL表达式的执行。

漏洞利用

环境中需要配置一个重定向设置,而且对重定向的参数不能进行限制(默认是没有限制

struts.xml

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>

    <!-- <constant name="struts.enable.DynamicMethodInvocation" value="true" /> -->
    <constant name="struts.devMode" value="false" />

    <!-- Add packages here -->
    <package name="S2-012" extends="struts-default">
        <action name="user" class="com.demo.action.UserAction">
            <result name="redirect" type="redirect">/index.jsp?name=${name}</result>
            <result name="input">/index.jsp</result>
            <result name="success">/index.jsp</result>
        </action>
    </package>
</struts>

在重定向的参数中传入一个OGNL表达式%{1+1}

明显可以看到被解析成了2,这也就造成了代码的执行
这样的话,只要传入S2-001中的poc就可以任意代码执行

漏洞分析

在UserAction.java中的execute()下断点

可以看到此时的参数信息,step over后会来到xwork-core-2.2.3.jar!/com/opensymphony/xwork2/DefaultActionInvocation.class

然后不断step over下去可以回到这个堆栈中

然后来到这这块代码区域

} else {
    this.resultCode = this.invokeActionOnly();
}

if (!this.executed) {
    if (this.preResultListeners != null) {
        Iterator i$ = this.preResultListeners.iterator();

        while(i$.hasNext()) {
            Object preResultListener = (PreResultListener)i$.next();
            PreResultListener listener = (PreResultListener)preResultListener;
            String _profileKey = "preResultListener: ";

            try {
                UtilTimerStack.push(_profileKey);
                listener.beforeResult(this, this.resultCode);
            } finally {
                UtilTimerStack.pop(_profileKey);
            }
        }
    }

    if (this.proxy.getExecuteResult()) {
        this.executeResult();
    }

由于不满足this.preResultListeners != null就直接跳到了如下代码中

if (this.proxy.getExecuteResult()) {
    this.executeResult();
}

也就是在这里执行了OGNL表达式,造成了的代码执行

漏洞修复

开启默认拒绝了恶意的OGNL表达式

对比了struts2.3.14和struts2.3.14.1

在XWorkConstans.class中

在DefaultConfiguration.class中添加了如下语句

Reference Links

https://github.com/vulhub/vulhub/tree/master/struts2/s2-012

总会有不期而遇的温暖. 和生生不息的希望。
原文地址:https://www.cnblogs.com/devi1/p/13486630.html