Struts2 方法调用远程代码执行漏洞(s2-032,CVE-2016-3081)

DBCA  3134天前

一、详细说明:

      2016年4月21日Struts2官方发布两个CVE,其中CVE-2016-3081官方评级为高。主要原因为在用户开启动态方法调用的情况下,会被攻击者实现远程代码执行攻击。

直接进行版本比对,我们可以看到针对这个问题,只对DefaultActionMapper.java这个文件进行了修改,修改内容如下:

Clipboard Image.png

我们可以看到只是把method成员变量的值进行了一次过滤,cleanupActionName这个方法是在对“action:”滥用的问题进行添加的,禁止了绝大多数的特殊字符。但是在后来的版本变更中忽略了之前的问题,将method也引入了Ongl表达式,代码在DefaultAction.java的invokeAction中:

   protected String invokeAction(Object action, ActionConfig actionConfig) throws Exception {
        String methodName = proxy.getMethod();

        if (LOG.isDebugEnabled()) {
            LOG.debug("Executing action method = #0", methodName);
        }

        String timerKey = "invokeAction: " + proxy.getActionName();
        try {
            UtilTimerStack.push(timerKey);

            Object methodResult;
            try {
                methodResult = ognlUtil.getValue(methodName + "()", getStack().getContext(), action);

我们可以看到methodName被带入到getValue了,熟悉Struts相关漏洞的朋友应该都明白这是什么意思,虽然后面被强制添加了一对圆括号,但是想办法语法补齐就好了。相对应的我们来看下在2.3.18版本之前的代码是怎么处理methodName的:

    protected String invokeAction(Object action, ActionConfig actionConfig) throws Exception {
        String methodName = proxy.getMethod();

        if (LOG.isDebugEnabled()) {
            LOG.debug("Executing action method = #0", methodName);
        }

        String timerKey = "invokeAction: " + proxy.getActionName();
        try {
            UtilTimerStack.push(timerKey);

            boolean methodCalled = false;
            Object methodResult = null;
            Method method = null;
            try {
                method = getAction().getClass().getMethod(methodName, EMPTY_CLASS_ARRAY);

在这里使用的是反射,所以在这个漏洞发布的时候,我曾一瞬间觉得又是一个骗CVE的鸡肋,但是事实上,这是一个威胁很大的漏洞。但是官方说的受影响版本Struts 2.0.0 - Struts Struts 2.3.28 (except 2.3.20.2 and 2.3.24.2)是不严谨的,应该是2.3.18-2.3.28(except 2.3.20.2 and 2.3.24.2)。

二、问题证明:

Clipboard Image.png

三、修复建议:

1)临时修复方案:禁用动态方法调用

修改 Struts2 的配置文件,将“struts.enable.DynamicMethodInvocation” 设置为 false,如

<constant name="struts.enable.DynamicMethodInvocation" value="false" />;

2)升级 Struts 版本至 Struts 2.3.20.2,Struts 2.3.24.2 或者 Struts 2.3.28.1 来修复漏洞,新版本下载地址:

https://struts.apache.org/download.cgi#struts2328

最新评论

Zebra  :  学习一下
3133天前 回复
昵称
邮箱
提交评论