漏洞复现
漏洞分析
Confluence这玩意在web.xml啥的文件里面没有明确定义,使用的是Tomcat的Initializer机制,在Tomcat启动时候加载Servlet之前会调用所有初始化器的onStartUp方法
initializers = {LinkedHashMap@51859} size = 3
{JasperInitializer@52323} -> null
{WsSci@52324} -> null
{SpringServletContainerInitializer@52325} -> {HashSet@52326} size = 4
key = {SpringServletContainerInitializer@52325}
value = {HashSet@52326} size = 4
0 = {Class@3333} "class com.atlassian.confluence.impl.webapp.LoggingBootstrapInitializer"
1 = {Class@52328} "class org.springframework.web.context.AbstractContextLoaderInitializer"
2 = {Class@52329} "class org.springframework.web.server.adapter.AbstractReactiveWebInitializer"
3 = {Class@3334} "class com.atlassian.confluence.impl.webapp.ServletsInitializer"
以上便是它的路由表,找到vm相关的可以发现*.vm对应的是ConfluenceVelocityServlet这个Servlet
再往下走来到了中规中矩的三方包操作,接下利用,这块可以参考老外的文章(https://github.blog/2023-01-27-bypassing-ognl-sandboxes-for-fun-and-charities/)
关于velocity这玩意,简单调了下,原理比较简单,说白了就是扫描字符串解析AST抽象语法树,然后从根节点出发递归计算每个子节点最后回归到根节点,整体呈树形结构
在`Velocity`中会将模板文件中使用到了`Velocity`语法部分字符串解析为`AST`抽象语法树,也就是拆分为各个节点,类似`JavaParser`对`Java`代码做抽象语法树解析,这里的Node接口类型实际上就是定义了一套接口规范,具体实现在每个类型节点又会有所不同,例如
#set( $labelValue = $stack.findValue("getText('$parameters.label')") )
可以看到存在两个子节点,分别是左右两边的表达式节点,整体呈树形结构,从根节点出发,一层一层递归解下去。
至于后面就是利用,在P神给出的POC里面使用的是表达式注入再内嵌表达式注入达到RCE效果,同类思路翻一翻Context上下文感觉还可以有其他切入点替代内嵌的表达式部分。
至于修复,看了下,好像自写了一个表达式过滤器,除此之外还加了些黑名单,这块懒得再拉docker镜像没去复测
结语
原文始发于微信公众号(安全之道):Confluence SSTI RCE(CVE-2023-22527)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论