洞态IAST自动检测S2-008漏洞

一、使用Dongtai-IAST检测S2-008漏洞

1. 启动在线靶场

登陆在线靶场:http://labs.iast.huoxian.cn:8081,启动S2-008环境,等待环境启动之后,点击访问靶场按钮即可前往靶场环境。该环境来源于vulhub和vulapps

2. 登陆**洞态IAST**网站:http://iast.huoxian.cn:8000/,查看漏洞检测结果

3. 进入搜索功能,分析完整的污点调用图

3.1 Source点

首先,在org.apache.struts2.dispatcher.mapper.DefaultActionMapper#handleSpecialParameters()方法中,调用Servlet接口的getParameterMap方法获取外部参数,形成初始污点

3.2 Propagator方法

污点经过一系列的处理,最终在com.opensymphony.xwork2.util.OgnlUtil#compile方法中,调用ognl.Ognl#parseExpression方法将污点数据传播为Ognl表达式对象

3.3 Sink方法

最后,在ognl.Ognl#getValue方法中,使用Ognl表达式对象的getValue方法获取Ognl表达式的值

二、S2-009 devmod漏洞手工分析

首先,使用struts.xml开启devmod

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

通过官方的描述是在DebuggingInterceptor这个类里。

    private final static String XML_MODE = "xml";
    private final static String CONSOLE_MODE = "console";
    private final static String COMMAND_MODE = "command";
    private final static String BROWSER_MODE = "browser";
    private final static String SESSION_KEY = "org.apache.struts2.interceptor.debugging.VALUE_STACK";
    private final static String DEBUG_PARAM = "debug";
    private final static String OBJECT_PARAM = "object";
    private final static String EXPRESSION_PARAM = "expression";
    private final static String DECORATE_PARAM = "decorate";

先是定义了一大堆常量。然后获取参数。

      boolean actionOnly = false;
        boolean cont = true;
        Boolean devModeOverride = FilterDispatcher.getDevModeOverride();
        boolean devMode = devModeOverride != null ? devModeOverride.booleanValue() : this.devMode;
        if (devMode) {
            final ActionContext ctx = ActionContext.getContext();
            String type = getParameter(DEBUG_PARAM);
            ctx.getParameters().remove(DEBUG_PARAM);
            ....

因为type是command所以进到这个判断语句

else if (COMMAND_MODE.equals(type)) {
                ValueStack stack = (ValueStack) ctx.getSession().get(SESSION_KEY);
                if (stack == null) {
                    //allows it to be embedded on another page
                    stack = (ValueStack) ctx.get(ActionContext.VALUE_STACK);
                    ctx.getSession().put(SESSION_KEY, stack);
                }
                String cmd = getParameter(EXPRESSION_PARAM);

                ServletActionContext.getRequest().setAttribute("decorator", "none");
                HttpServletResponse res = ServletActionContext.getResponse();
                res.setContentType("text/plain");

                try {
                    PrintWriter writer =
                            ServletActionContext.getResponse().getWriter();
                    writer.print(stack.findValue(cmd));
                    writer.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }

可以看到使用cmdString类型变量来存放expression参数的值。然后stack.findValue(cmd)

然后findValue(String expr)findValue(String expr, boolean throwExceptionOnFailure)

 public Object findValue(String expr) {
        return findValue(expr, false);
    }

public Object findValue(String expr, boolean throwExceptionOnFailure) {
        try {
            setupExceptionOnFailure(throwExceptionOnFailure);
            return tryFindValueWhenExpressionIsNotNull(expr);
        } catch (OgnlException e) {
            return handleOgnlException(expr, throwExceptionOnFailure, e);
        } catch (Exception e) {
            return handleOtherException(expr, throwExceptionOnFailure, e);
        } finally {
            ReflectionContextState.clear(context);
        }
    }

接着调用tryFindValueWhenExpressionIsNotNull(expr)

private Object tryFindValueWhenExpressionIsNotNull(String expr) throws OgnlException {
        if (expr == null) {
            return null;
        }
        return tryFindValue(expr);
    }

接着调用tryFindValue(expr)

private Object tryFindValue(String expr) throws OgnlException {
        Object value;
        expr = lookupForOverrides(expr);
        if (defaultType != null) {
            value = findValue(expr, defaultType);
        } else {
            value = getValueUsingOgnl(expr);
            if (value == null) {
                value = findInContext(expr);
            }
        }
        return value;
    }

接着调用getValueUsingOgnl

    private Object getValueUsingOgnl(String expr) throws OgnlException {
        try {
            return ognlUtil.getValue(expr, context, root);
        } finally {
            context.remove(THROW_EXCEPTION_ON_FAILURE);
        }
    }

接着调用ognlUtil.getValue(expr, context, root)

就又到了

    public Object getValue(String name, Map<String, Object> context, Object root) throws OgnlException {
        return Ognl.getValue(compile(name), context, root);
    }

和之前的001都一样了。

账号申请

  • 洞态IAST合作伙伴计划之整体开源联合开发,申请方式请扫描下方二维码

g)

  • 如需加入技术讨论群,扫描二维码添加微信并备注"洞态IAST-加群",工作人员将拉您进群

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值