先拿exp打一遍抓个包
可以看到流量访问的是pages/createpage-entervariables.action
首先要搞清这个路由对应的处理
而在web.xml里

    <servlet-mapping>
        <servlet-name>action</servlet-name>
        <url-pattern>*.action</url-pattern>
    </servlet-mapping>

*.action都是交给com.atlassian.confluence.servlet.ConfluenceServletDispatcher的
再跟下去会发现继承自webwork、xwork 这方面我0基础 于是选择看看别人的分析(逃
看了别人的文章后 找到了action的配置文件 里面对应的是这里

    <action name="createpage-entervariables" class="com.atlassian.confluence.pages.actions.PageVariablesAction">
            <interceptor-ref name="defaultStack"/>
            <result name="error" type="velocity">/pages/createpage-entervariables.vm</result>
            <result name="input" type="velocity">/pages/createpage-entervariables.vm</result>
            <result name="success" type="velocity">/pages/createpage-entervariables.vm</result>
            <result name="novariables" type="velocity">/pages/createpage.vm</result>
        </action>

com.atlassian.confluence.pages.actions.PageVariablesAction的execute里返回input、error、success都会渲染createpage-entervariables.vm 然而调了下返回的是novariables 所以看看createpage.vm吧

继承树真的是非常壮观了

因为漏洞在模版里 所以就直接看重点了
#tag (“Hidden” “name=’queryString'” “value=’$!queryString'”)
传的参数由#tag处理 但是vm没有这玩意 是自定义的
在vm配置文件里可以找到对应的处理类
之后在他的父类中的render下断点
处理标签是在processTag方法里
接下来的内容需要一些ognl基础


跟到最后可以看到调用了OgnlValueStack.findvalue
这里出现第一个问题:
输入的内容是被单引号包裹的 想注入任意的ognl表达式需要逃逸单引号 但是单引号被转义成了html实体 而ognl的解析过程中会对unicode进行解码 所以通过\u0027即可绕过

然后就是第二个问题:如何绕过安全检查

分段来看

set.add("ognl.ASTStaticMethod");
        set.add("ognl.ASTStaticField");
        set.add("ognl.ASTCtor");
        set.add("ognl.ASTAssign");
        UNSAFE_NODE_TYPES = Collections.unmodifiableSet(set);

看名字就能猜到了 ban的是ognl中的静态⽅法、静态属性、构造方法、赋值

 set = new HashSet();
        set.add("class");
        set.add("classLoader");
        UNSAFE_PROPERTY_NAMES = Collections.unmodifiableSet(set);

这里ban的是class和classLoader属性

set = new HashSet();
        set.add("getClass()");
        set.add("getClassLoader()");
        UNSAFE_METHOD_NAMES = Collections.unmodifiableSet(set);

也很好理解

set = new HashSet();
        set.add("#_memberAccess");
        set.add("#context");
        set.add("#request");
        set.add("#parameters");
        set.add("#session");
        set.add("#application");
        UNSAFE_VARIABLE_NAMES = Collections.unmodifiableSet(set);

并没有ban Class.forName 所以

这里遇到了个挺迷惑的问题没解决

asadasasdaadasd\u0027%2b{Class.forName(\u0027java.lang.Runtime\u0027).getMethod(\u0027getRuntime\u0027)}%2b\u0027asdsad\u0027%2b\u0027

获取不到method

asadasasdaadasd\u0027%2b{Class.forName(\u0027java.lang.Runtime\u0027).getDeclaredMethod(\u0027exec\u0027,Class.forName(\u0027java.lang.String\u0027))}%2b\u0027asdsad\u0027%2b\u0027

exec一切正常

于是就拿jsengine打了..
后续又看了下别的宏 发现ParamDirective里也存在一个ognl表达式解析
但是搜了一遍vm文件 没有满足条件的 就放了

Categories: 技术

0 Comments

发表评论

Avatar placeholder

您的电子邮箱地址不会被公开。 必填项已用*标注