CVE-2022-26134 Confluence OGNL RCE 漏洞深入分析和高版本绕过沙箱实现命令回显
source link: https://paper.seebug.org/1912/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
CVE-2022-26134 Confluence OGNL RCE 漏洞深入分析和高版本绕过沙箱实现命令回显
21小时之前2022年06月06日漏洞分析
作者:且听安全
原文链接:https://mp.weixin.qq.com/s/nCMtSD7QH8ai6fpurJBXTg
最近 Confluence 官方通报了一个严重漏洞 CVE-2022-26134 :
从漏洞描述来看,这仍然是一个 OGNL 表达式注入漏洞。影响版本如下:
- from 1.3.0 before 7.4.17
- from 7.13.0 before 7.13.7
- from 7.14.0 before 7.14.3
- from 7.15.0 before 7.15.2
- from 7.16.0 before 7.16.4
- from 7.17.0 before 7.17.4,
- from 7.18.0 before 7.18.1
补丁描述:
主要是修改了 xwork-1.0.3-atlassian-10.jar
。下面将深入分析漏洞原理,并尝试绕过沙箱构造命令执行结果回显。
新版本主要是修改了 xwork-1.0.3-atlassian-10.jar
。首先简单进行一下补丁对比:
改动的地方很多,但是最关键的地方位于 ActionChainResult#execute
函数,对提取 finalNamespace
和 finalActionName
的过程进行了更新。
Confluence 基于 Struts 架构进行开发。我们首先以登录请求为例,对 Confluence 请求处理的流程进行动态调试。访问 /login.action
,经过一系列 Filter
处理后,将进入Servlet 的分发器 ServletDispatcher
(本质上是其子类 ConfluenceServletDispatcher
对象):
分别通过函数 getNameSpace
、 getActionName
、 getRequestMap
、 getSessionMap
、 getApplicationMap
提取相应参数,对应关系如下:
getNameSpace(request)
->namespace
getActionName(request)
->actionName
getRequestMap(request)
->requestMap
getParameterMap(request)
->parameterMap
getSessionMap(request)
->sessionMap
getApplicationMap()
->applicationMap
然后调用 serviceAction
函数,进入子类 ConfluenceServletDispatcher
的 serviceAction
函数:
实例化 DefaultActionProxy
对象,调用其 execute
函数:
进入 DefaultActionInvocation#invoke
:
这里开始调用 Struts Interceptor 拦截器对象对请求进行处理, DefaultActionInvocation
对象拦截器集合 interceptors
一共有 32 个:
函数 invoke
尝试通过 next
获取下一个拦截器对象,然后调用其 intercept
方法,大部分 Interceptor
对象的 intercept
函数格式如下所示:
继续调用 DefaultActionInvocation#invoke
,从而形成迭代循环。但是在调试中我们发现也有特殊的一些 Interceptor
,比如 ConfluenceAccessInterceptor
:
当满足一定条件时并不会继续调用 DefaultActionInvocation#invoke
,而是返回字符串 notpermitted
,我们分析一下 isAccessPermitted
函数:
主要是通过请求的 *.action
和 methdName
,来判断当前用户 currentUser
是否有访问权限。也就是说,当访问一个无权访问的 *.action
时,DefaultActionInvocation#invoke
在迭代调用到 ConfluenceAccessInterceptor#intercept
后,将返回 notpermitted
并赋值给 resultCode
,从而跳出迭代。我们替换测试请求为 /index.action
:
当处理到 ConfluenceAccessInterceptor
拦截器时,将不会继续迭代调用下一个拦截器,而是继续往下走,进入 executeResult
函数:
进入 ActionChainResult#execute
:
提取 namespace
参数,并调用 translateVariables
函数,进入:
典型的 OGNL 表达式解析过程,前面分析中可知, namespace
参数通过 ServletDispatcher#getNameSpace
函数获取,查看定义:
可见 namespace
取值为请求 servletPath
最后一个 /
之前的部分。
根据上面正则表达式规则,要想触发 OGNL 解析,我们很容易构造出相应的 URL :
成功触发 OGNL 表达式注入。
沙箱绕过与命令执行
网上现在已经公开的一些利用方式简单粗暴,只能针对 v7.14 及以下系列有效,因为从 v7.15 系列开始,Confluence 在 OGNL 表达式解析时加入了沙箱设置:
进入 isSafeExpression
函数:
主要的黑名单如下:
(1) unsafePropertyNames
(2) unsafePackageNames
(3) unsafeMethodNames
0 = "getClass"
1 = "getClassLoader"
白名单 allowedClassNames
如下:
此外,对成员函数等也进行了检查( containsUnsafeExpression
函数 ):
小伙伴看到这里,应该很容易想到多种绕过的方法,感兴趣的小伙伴可以进入漏洞空间站进行交流。其中一种实现命令执行结果回显的方式如下(适用全部受影响的版本):
本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/1912/
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK