Atlassian Confluence 模板注入漏洞(CVE-2023-22527)
type
status
date
slug
summary
tags
category
icon
password
AI summary
文章首发自奇安信攻防社区
漏洞分析
漏洞原理
在Confluence中,.vm文件是使用Velocity模板语言创建的模板文件。Velocity是一个基于Java的模板引擎,它允许你使用简单的标记语言来引用Java对象和方法,从而动态生成HTML、XML或任何文本格式的内容。
处理.vm文件的主要类是ConfluenceVelocityServlet。这个Servlet负责接收和处理来自浏览器的请求,加载和解析.vm模板,执行其中的Velocity代码,然后将生成的HTML发送回浏览器。
这次的漏洞点位于:/template/aui/text-inline.vm文件,可以直接通过/template/aui/text-inline.vm访问
$stack.findValue("getText('$parameters.label')")意味着从请求中获取的label参数的值传入了$stack.findValue,由此可以判断这里存在模版注入!调用分析
.vm文件由
ConfluenceVelocityServlet处理
继续跟进
这里跟进
handleRequest(),可以发现从URI中获取vm文件路径,传入getTemplate()来返回模版对象

然后传入
mergeTemplate()函数处理
这里创建新的PageContext,获取其输出流,准备进行模板合并和输出操作。
继续跟进
template.merge()
跟进到merge的重载函数
由于传入的macroLibraries为空,所以直接执行try逻辑
- 调用
ica.pushCurrentTemplateName(this.name);将当前模板的名称压入到ica的模板名堆栈中。这是为了在嵌套模板的情况下能够追踪到当前正在处理的模板名称。
- 调用
ica.setCurrentResource(this);将当前模板对象设置为ica的当前资源。这是为了让ica知道当前正在处理的模板资源。
- 最后,通过调用
((SimpleNode)this.data).render(ica, writer);进行模板渲染
省略中间的部分渲染过程,跟进到
ASTReference#execute()
这里从上下文中获取OgnlValueStack,继续跟进


这里从请求中获取到参数,然后通过
Object obj = method.invoke(o, params);执行,继续跟进
经过几层invoke调用后,来到了最终vm文件模版的位置——
OgnlValueStack.findValue()
随后,传给label参数的OGNL表达式语句被执行

绕过沙箱RCE
对于Velocity模版引擎,可以使用如下方法:
.KEY_velocity.struts2.context-> (StrutsVelocityContext)ognl(org.apache.struts2.views.jsp.ui.OgnlTool)struts(org.apache.struts2.views.velocity.result.VelocityStrutsUtils)
org.apache.struts2.views.jsp.ui.OgnlTool 类在没有 OgnlContext 的情况下调用了 Ognl.getValue()。
- 正常的 Struts OGNL 执行:
当 Struts2 处理 HTTP 参数或标签时,它会创建一个 OgnlContext。为了安全,Struts 会向这个 Context 中注入一个 SecurityMemberAccess 对象。这个对象充当“看门人”,禁止访问静态方法、禁止访问 java.lang.Runtime、禁止访问 _memberAccess 等。
- Velocity 的 OgnlTool 漏洞:
- OgnlTool.findValue 的内部实现最终会调用原生 OGNL 库的 Ognl.getValue(expression, context, root)。
- 关键点: 如果 OgnlTool 在调用 Ognl.getValue 时,传入的是一个新的 Context,或者是没有配置 SecurityMemberAccess 的 Context,那么 OGNL 就会使用默认的、宽松的 DefaultMemberAccess。
- 结果: DefaultMemberAccess 允许访问任何 public 方法,包括 Runtime.exec()。因此,Struts 的黑名单策略完全失效。
在 Velocity 模版渲染时,如果上下文中存在 $ognl (即 OgnlTool 实例),攻击者可以调用 $ognl.findValue("payload")。

漏洞复现
- 网站首页如下图:

- 使用如下POC进行漏洞复现

Loading...