浅析Confluence_CVE-2023-22527
前言
碎碎念
纵使有前言万语,打开编辑器,但是不知道怎么开头,也不知道如何下笔,敲了删,删了敲,纠结,彷徨,还是随便写写,反正也没人看,当作一段时间的碎碎念吧。
最近一段时间家里发生了一些事,包括我今年也面临毕业,可是我那三流的末流学校在校招当中犹如有案底一般不被待见。所以不管是工作也好生活也罢,最近状态一直不在线。我想跳出这样一个不良的状态。年关将至,趁着这段时间好好给自己放个假,调整一下自己,新的一年自己也要有些成长。
关于家里:我想在爷爷剩下的时间里,尽可能的多陪陪他老人家,从小在爷爷奶奶陪伴下成长,我也并不是放荡不羁,反之我觉得自己算得上是个懂事的孩子。
关于工作:学校虽在末流,可是我也有一颗积极向上的心。我觉得能限制我自己的只有我自己。我也想当一个大厂的社畜,可是连机会都没有。目前只能是走一步看一步,今年的就业形势太糟糕了。大厂各种裁员,小厂坚持不住也有倒了的。总之怨天尤人没有用,别人都可以为什么你不可以?努力吧
关于学习:工作之后才知道,学了那么多东西真用的时候不一定用得上,但是一定得知道。因为目前一直在实习,学习的重心也偏向安全研究,秋招过后,我才知道自己不属于这个方向。后面还得加强广度学习。等到真找到正式工作之后,再具体定学习重心吧。
漏洞简述
本次Confluence的洞实际上是SSTL(服务端模板注入漏洞)。因为之前没有了解过这类的漏洞,所以在分析之前还看了几篇相关的文章,链接放在下面,仅供参考。
源码分析
Confluence使用的是Velocity模板,具体的细节在上面SSTL基础中有涉及到。它是以.vm结尾的文件。而在Confluence中处理.vm的类是ConfluenceVelocityServlet
。它主要负责处理请求和解析.vm模板,处理后将结果返回给浏览器。
进入到doPost
之后会调用doRequest
,其中我们只需要关注两个标红的地方。
首先是第一处,它通过获取请求路径之后,返回一个template对象。
第二处,我们跟进
前面都是获取一些基础的对象,在try当中获取了PageContext的输出流,将模板和context进行合并将结果保存到输出流之中。我们跟进看下具体实现逻辑。
发现在其内部的重载函数中获取了传入的macroLibraries为空,所以直接会跳到try的逻辑中。
- 调用
ica.pushCurrentTemplateName(this.name);
将当前模板的名称压入到ica
的模板名堆栈中。这是为了在嵌套模板的情况下能够追踪到当前正在处理的模板名称。 - 调用
ica.setCurrentResource(this);
将当前模板对象设置为ica
的当前资源。这是为了让ica
知道当前正在处理的模板资源。 - 最后,通过调用
((SimpleNode)this.data).render(ica, writer);
进行模板渲染
跟进最后渲染的堆栈信息如下:
然后一直到ASTReference#execute
中
通过getVariableValue
获取context
中的this.rootString
的变量。然后调用this.jjtGetChild(i).execute
我们再次跟进查看逻辑
从context中获取到参数后,经过几层调用后会来到OgnIValueStack#findValue
其中堆栈信息如下:
内部实现:
最后会再次调用一边上述流程最终会来到 UberspectImpl#invoke
其中堆栈信息如下:
最终经过一系列的Invoke调用来到UberSpectImpl#invoke
的doInvoke中实现将label参数的OGNL表达式传入执行。
漏洞复现
1 |
|