参考:
对 Confluence CVE-2023-22515 的一点分析
Struts2 系列漏洞调试总结 | 素十八
先贴一张su18师傅总结的文章图片,建议熟读以及背诵
漏洞成因
对 Confluence CVE-2023-22515 的一点分析
pen4uin师傅在微信公众号已经发过一篇浅析文章,而我当时也是差一点就自己复现成功了,但由于对Xworks2这个框架的特性不熟悉,所以卡在最后一步。
这个漏洞是一个类似于变量覆盖的漏洞,我们可以覆盖系统是否已经完成安装的标识符吗,这样就可以让他重新安装设置一次管理员了。
图都是偷的,因为我懒。根据diff不难发现对setter和getter进行了修复,然后再根据前言中的流程图,在拜读完su18师傅的stucts2全解析文章后,我对这个框架又有了一些理解,其中ParametersInterceptor
就是我们心心念念的漏洞点了。我们现在只需要找到可以触发这个监听器的路由即可。
根据企鹅师傅的文章我们知道了个思路,就是寻找有defaultstack
和opensearch
这两个stack配置的action,这样即可触发上述的监听器。
漏洞分析
思路分层
Xworks2 对于 interceptor的处理比较有特性,当我们传入一个参数时,他会通过action及其父类的setter或者getter方法对该属性进行赋值。action有一个setMember方法,我们在url只需要传入一个uri?member=1
就可以对member属性进行赋值。个人认为这还是比较危险的。万一存在JNDI注入之类的呢。
在这个包下有stucts.xml文件,我们直接CTRL+F搜索即可了。
有很多action,我这里就随便选了一个NotPermittedAction
当做分析了,那我们来捋一下思路。
企鹅师傅的思路在响应title之后可以逆推分析,最终需要污染setupComplte属性setupComplete
在com.atlassian.config.ApplicationConfiguration
类的属性里。那我们现在需要做的就是怎么得到config类,回想一下补丁中还有个BootstrapStatusProviderImpl
他又刚好有个getter可以获取config,那么我们还需要找个类BootstrapStatusProvider
。
此处省略一万次继承,最后到了ConfluenceActionSupport
这不就又刚好获取到了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方法上。
然后访问payload开始操作。
进入方法内部
首先获取了当前路由所处的action,然后初始化stack,进入setParameters方法内部
首先会进行一个黑名单检测,这个isAcceptableParameter
方法主要的功能是检测传入的参数的键的长度是否长于100,是否含有黑名单字符。我们这里只是单纯的变量污染所以很单纯不会被检测到。
然后就进入newstack的setparam方法去了,这个newstack实际上就是一个Ognl对象。
OgnlValueStack.setValue
在这里真正调用OgnlUtil的setvalue方法,假如这里没有上面的黑名单,那肯定存在一个OGNL的RCE漏洞了。
调用Ognl.setvalue,到这里就是纯粹的Ognl的AST语法了。
从这里的setvalue来看已经有一点雏形了,这里root就是对应的action,value就是我们设置的那个setup属性。
经过不断的迭代,在setValueBody方法内,我们会获取第一个属性bootstrapStatusProvider
然后此处省略一万步的迭代。
随之进入的是OgnlRuntime方法内部
getProperty
最后在OgnlRuntime.getProperty
方法下获取到了BootStrap对象。
反射调用getter方法获取到对象
之后的流程也就一模一样了。我就不继续跟进咯。
漏洞复现
在输入完payload后,我们用burpsuite抓个包。
1 | POST /setup/setupadministrator.action HTTP/1.1 |
已经可以在这个界面设置一个新的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.