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


    概述

    struts2 029漏洞已经爆出一段时间,网上有一些相关分析,首先,漏洞确定是出现在OGNL解释执行的过程,具体漏洞测试poc网上已经有很多,我在2.2.1、2.3.24.1、2.3.25、2.5beta3、2.3.26上面测试都可以执行,不过修改的安全参数稍微不同。

    2.2.1只需要下面几个:

    #_memberAccess['allowPrivateAccess']=true

    #_memberAccess['allowProtectedAccess']=true

    #_memberAccess['allowPackageProtectedAccess']=true

    #_memberAccess['allowStaticMethodAccess']=true

    2.3.24.1和2.5beta3则需要:

    #_memberAccess['allowPrivateAccess']=true

    #_memberAccess['allowProtectedAccess']=true

    #_memberAccess['excludedPackageNamePatterns']=#_memberAccess['acceptProperties']

    #_memberAccess['excludedClasses']=#_memberAccess['acceptProperties']

    #_memberAccess['allowPackageProtectedAccess']=true

    #_memberAccess['allowStaticMethodAccess']=true

    2.3.25和2.3.26 则需要

    #_memberAccess['excludedPackageNames']=#_memberAccess['acceptProperties']

    #_memberAccess['allowPrivateAccess']=true

    #_memberAccess['allowProtectedAccess']=true

    #_memberAccess['excludedPackageNamePatterns']=#_memberAccess['acceptProperties']

    #_memberAccess['excludedClasses']=#_memberAccess['acceptProperties']

    #_memberAccess['allowPackageProtectedAccess']=true

    #_memberAccess['allowStaticMethodAccess']=true

    话说官方说的升级到2.3.25就没事了是咋回事?

    分析

    下面就对2.3.25进行跟踪分析一下。

    首先官网还没有2.3.25的编译版本下载,有的只是beta版。而beta版的代码经过对比,发现还是有很多与2.3.25不同的,故github 2.3.25源码,然后mvn install -Dmaven.test.skip=true编译。

    编译好之后,部署测试程序。Poc测试代码如下:

    这里先说明一下,漏洞的根源是调用findString、findValue等函数。所以切换到
    /struts-STRUTS_2_3_25/core/src/main/java/org/apache/struts2/components下面,对这里的源码进行查找findValue参数,可以发现很多类都有调用

    下面我们对textfield这个标签举例进行跟踪分析。Textfield有很多属性,

    我们先看下size属性,通过findString查找size,findString的定义如下:

    可以看到它实际调用findValue(expr,String.class),定义如下:

    而这个函数判断传入的如果是String类的话,会调用TextParseUtil.translateVariables,先解析字符串后在去执行expr,否则直接执行expr。getStack().findValue()就是代码被解释执行的位置,这时候的expr的%{}会被去掉。

    这里注意到一个问题,就是相对2.3.25之前的版本,此处多了一个ComponentUtils.containsExpression(expr)判断,该函数是检测expr表达式中是否同时包含”%{“和”}”,如果是,返回真。也就是检测传入的字符串是不是标准的OGNL表达式。这个判断可能会有点用。比如,如果我们想通过size参数带入执行代码,如果我们直接写size=”expr”,那么expr进入findValue(expr,String.class)后过不了ComponentUtils.containsExpression(expr)的判断,什么都不执行直接返回。想要执行,必须写成%{expr}。其他用途还没看出来。

    下面还要说下readonly属性,这个属性是布尔型,而findValue(expr,String.class)中如果不是String类型的话,不需要%{}就可以直接执行,也就是说readonly=”expr”就会被执行。

    上面说的是OGNL代码的正常执行过程,代码只被执行一次。而这次漏洞报的是双重执行,也就是expr在一次请求中存在被解释执行两次的情况。这个情况在i18n源码中存在,具体细节请参考http://www.freebuf.com/vuls/99432.html。通过图2,可以发现在UIBean中也存在这样的情况。进一步查找,可以发现可疑情况:

    其中UIBean中有三处出现对name属性进行执行的操作,查看代码逻辑发现果然有问题:

    其中就有TextField。而UIBean的属性也不少。其中的name和value值得关注。

    先是

    得到name的string,之后到这里

    会先尝试获取value的值,如果value为空,那么就二次解释执行了name。并且在执行前给name加上了”%{}”。最终造成二次执行。

    而UIBean被很多类继承:

    类似的textarea、label、hidden等都存在二次执行问题。

    另外在2.3.25中多了#_memberAccess['excludedPackageNames']

    所以必须将其清空,我们的payload才能执行。

    结论

    该漏洞可利用性比较困难,能够双重执行的属性位于name中,而我们通常可以传参的地方是value(不排除哪个程序员可以让你操控name属性值,同时你的value值还为空的情况),查找value的执行情况:

    出现在Param.java和UIBean.java中,而阅读代码后,发现这两次执行都是位于不同分支中,不能造成二次执行的情况。

    所以此次漏洞危害不算大,不过就是官方说的修复有点不理解。最后给出我测试的2.3.25和2.3.26的完整war包,测试uri:http://localhost:8080/2.3.25/http://localhost:8080/2.3.26/

    执行的命令是touch /tmp/fuckp4e。部署并访问uri后,如果出现此文件,说明存在漏洞。

    总会有不期而遇的温暖. 和生生不息的希望。
  • 相关阅读:
    为什么数据库连接很消耗资源 转
    在Eclipse中编写servlet时出现"The import javax.servlet cannot be resolved" 问题解决办法
    multipart/form-data post 方法提交表单,后台获取不到数据
    java 数据库查询Date类型字段 没有了时分秒 全为 00 的解决办法
    Eclipse/myEclipse 代码提示/自动提示/自动完成设置(转)
    PL/SQL破解方法(不需要注册码)
    Java
    tomcat开发环境配置
    文件操作权限
    Java版office文档在线预览
  • 原文地址:https://www.cnblogs.com/devi1/p/13486627.html
Copyright © 2020-2023  润新知