1. 导语
知名企业维基软件Confluence于8月25日爆出了一个严重漏洞 CVE-2021-26084,此漏洞的危害是攻击者可以不需登录直接在Confluence服务端执行任意代码。由于该产品在互联网行业里使用广泛,导致 8月底漏洞PoC 释出后,外部黑客开始大量传播利用。届时,有12000余台互联网公开服务器受到此漏洞的影响。
(参考:https://censys.io/blog/cve-2021-26084-confluenza/)
-
产生此漏洞的原理是什么?
-
通过哪些接口和参数可以触发该漏洞?
-
为什么触发该漏洞不需要任何权限?
-
是否存在安全机制限制此漏洞的利用?
针对以上问题,本文会展开进行分析。
2. 漏洞解析
2.1. 漏洞简介
Confluence Server和Confluence Data Center存在一个OGNL注入漏洞,能够导致一个未授权的用户在Confluence Server或Confluence Data Center实例上远程执行任意命令。该漏洞影响的版本如下:
2.2. 漏洞触发点
漏洞sink点存在于confluence/pages/createpage-entervariables.vm模板中,如下所示:
这里使用到的是velocity模板的VTL语言,$foo和$!foo都表示引用的变量。此处引用的变量通过struts框架的ognl引用了当前访问action的属性值,可以通过GET/ POST 请求参数赋值,因此我们可以直接通过请求参数控制velocity模板中的参数queryString。
模板中用到的tag命令是 WebWork 框架下的,WebWork 提供了一系列标签能够帮助快速构建前端页面,但是在结合velocity的时候,一些jsp标签就需要使用tag/bodytag命令来进行转换:
在转换的过程中,会将渲染出来的tag中的各个属性(这里是name和value)的值进行ognl解析,由于在tag转换之前$!queryString已经在Velocity层进行过一次ognl解析渲染,转换时就造成了二次ognl解析,因此我们可以通过queryString参数来进行ognl注入。
我们还可以发现,linkCreation具有同样的特性,因此linkCreation也可以用来做ognl注入。
2.3. 漏洞接口
我们在confluence-7.12.4.jar/xwork.xml中可以看到doenterpagevariables.action和createpage-entervariables.action使用了存在漏洞的模板createpage-entervariables.vm,这两个接口都属于/pages的namespace下,因此请求/ pages / doenterpagevariables.action和 / pages / createpage-entervariables.action 都可以触发该漏洞。
2.4. 权限分析
请求以上两个接口都是不需要权限的,那么代码中是如何判断哪些接口需要权限的呢?经分析有以下四处检查权限的地方:
2.4.1. SecurityFilter
在confluence/WEB-INF/classes/seraph-paths.xml配置了针对于/admin/路径下的action,要求有登录用户且有confluenceadmin_seraph_role角色的权限。
com.atlassian.seraph.filter.SecurityFilter过滤器会对此配置进行检查:
2.4.2. ConfluenceAccessInterceptor
在ConfluenceAccessInterceptor拦截器会进行访问页面的权限校验,如果权限校验不过,就会返回notpermitted的结果码,不再执行原有接口的目标函数且会返回notpermitted响应的页面:
此拦截器检查权限的时候主要是判断要请求的函数、类、类所在包有没有权限相关的注解,相关注解如下:(参考链接:https://docs.atlassian.com/ConfluenceServer/javadoc/7.1.0/)
而如果要访问的函数、类、类所在包都没有权限相关注解,默认是允许访问的。漏洞相关的类就是属于这种情况。
2.4.3. UserAwareInterceptor
在UserAwareInterceptor拦截器中会检查访问的Action类是不是UserAware接口类的实现类。如果是,则也会要求有用户登录,且会检查用户是否有访问此页面的权限;/users路径下大部分页面的Action都属于UserAware接口类的实现类,因此需要有用户登录。
2.4.4. PermissionCheckInterceptor
在PermissionCheckInterceptor拦截器中会调用Action类的isPermitted方法检查访问该Action的权限,Action继承的父类的isPermitted方法要求有用户登录,只有子类Action覆盖了isPermitted方法且返回true时才可以允许不需要用户登录,比如漏洞所在的Page-VariablesAction就实现了isPermitted方法,会直接返回true不需要做权限校验。
根目录下的很多页面就是因为实现了直接返回true的isPermitted方法因此不需要权限就可以访问,比如warmconfluence:
2.5. 防护绕过
在触发漏洞最后执行ognl语句之前,会执行SafeExpressionUtil.isSafeExpression校验ognl语句是否存在恶意,一些常用的函数和变量都被禁用了:
但是仍然可以绕过这些限制执行任意命令,绕过手段包括:
另外注意单双引号会在执行ognl表达式之前,被html编码导致不能使用,可以使用unicode编码的形式绕过此处的单双引号输入限制,比如使用\u0027代替单引号。
2.6. 官方修补方式
在confluence7.12.5中可以发现,官方的修补就是将createpage-entervariables.vm模板中的queryString和linkCreation的velocity变量引用去掉了,这样就不再存在二次ognl解析的问题。
3. 总结
-
漏洞出现的原因是使用velocity模板时产生了二次ognl解析的问题;
-
漏洞入口包括/pages/doenterpagevariables.action和/pages/createpage-entervariables.action;攻击参数为queryString或linkCreation,可以使用POST也可以使用GET参数传递;
-
在Confluence代码逻辑中默认有四处会进行权限校验,包括:
SecurityFilter、ConfluenceAccessInterceptor、UserAwareInterceptor、PermissionCheckInterceptor,此漏洞恰巧不需要校验权限;
4. 附录
4.1. 相关链接
漏洞公告:https://confluence.atlassian.com/doc/confluence-security-advisory-2021-08-25-1077906215.html
4.2. 环境搭建过程
1)可从历史版本下载页面(https://www.atlassian.com/software/confluence/ download-archives)获取到有漏洞的版本,这里笔者下载了7.12.4版本的atlassian-confluence-7.12.4.tar.gz压缩包,然后需要配置一个数据库供confluence使用,我们这里选择配置一个postgresql数据库。解压缩该压缩包到一个linux服务器,编写confluence/WEB-INF/classes/confluence-init.properties,将最后一行confluence.home的值修改为压缩包解压的路径:
2)运行bin/start-confluence.sh。
3)用浏览器访问搭建服务器的8090端口,就可以看到安装页面了。这里选择安装试用版,按照页面提示申请一个试用的license。
4)在Set up your database阶段输入配置好的postgresql连接地址和用户。
5)按照页面提示选择创建Example Site,再创建管理员用户即可。
-END-
点击关注“腾讯IT技术”
探索前沿领域技术,获悉腾讯实践经验
文章评论