漏洞分析 | JumpServer未授权访问漏洞(CVE-2023-42442)

漏洞概述

JumpServer是广受欢迎的开源堡垒机,是符合 4A 规范的专业运维安全审计系统,帮助企业以更安全的方式管控和登录所有类型的资产,实现事前授权、事中监察、事后审计,满足等保合规要求。

网宿安全演武实验室监测到JumpServer存在未授权访问漏洞(CVE-2023-42442)。由于JumpServer某接口未做授权限制,允许任何未经身份验证的用户获取session信息,最终结合目录权限绕过下载录像文件,其中可能包含敏感信息,如密码、历史命令等。

受影响版本

受影响版本:v3.0.0 - v3.6.3

漏洞分析

JumpServer使用了Django Rest Framework的权限模型来验证用户权限,而此次漏洞成因是自定义权限出了问题,所以先了解一下如何正确地实现自定义权限。

BasePermission是Django Rest Framework提供的基类。开发者可以通过继承permissions.BasePermission 来创建自定义的权限类,并且通常要实现has_permission、has_object_permission中的一个或两个方法。

下面分别举例说明各方法的实际作用:

首先是has_permission,这里对列入黑名单的IP进行全局权限检查,如果IP已被列入黑名单,则拒绝该请求。

接着是has_object_permission,它的作用就是允许对象的所有者对其进行编辑,而对于其它用户只允许进行只读操作,比如对于GET、HEAD、OPTIONS,即只读操作,返回 True。

而对于POST、PUT、PATCH、DELETE,则需要验证请求的用户是否是对象的所有者,如果对象的 owner 属性与请求的用户相匹配,则返回 True,表示用户有权限执行操作,否则返回 False,表示用户无权限执行操作。

但正如Django Rest Framework官方所述,has_permission方法可以提供一个基本的权限检查,用于验证用户是否具有访问整个API视图的权限。而has_object_permission方法可以在has_permission验证通过后,进一步验证用户是否具有访问特定对象的权限,所以为了确保安全性,最优的方式就是在自定义权限类中同时实现这两个方法。

回到漏洞代码,不难发现IsSessionAssignee只实现了has_object_permission。

搜索该类的使用情况:

只有SessionViewSet使用,这是用来处理与Session相关的 API 请求的视图集,相关接口可以通过JumpServer提供的API文档进行查阅。而此次漏洞泄露的信息为session列表,获取的信息如下:

至此,第一个API未授权访问导致session信息泄露已经分析结束,接下来就是利用目录权限绕过下载录像文件。

我们可以先通过JumpServer提供的API文档,尝试未授权下载录像文件:

发现该接口做了鉴权:

那就只能去安全版本查看更新日志,发现这一条涉及到了静态录像文件路径:

查看对应的http_server.conf后可得,录像文件存放于/media/replay/下:

进入docker内查看完整目录结构,即/media/replay/{time}/{id}.cast.gz(Linux)或/media/replay/{time}/{id}.replay.gz(Windows):

按照这个格式构造请求后发现被禁止访问了:

这里先看下静态文件是如何管理的:

不难发现是使用了第三方模块django-private-storage。这个模块就是将敏感的文件存储在受保护的位置,并通过授权的方式提供对这些文件的访问。

而我们需要关注的,是它用于验证对私有文件访问权限的配置选项PRIVATE_STORAGE_AUTH_FUNCTION。

全局搜索后发现,该配置选项指定了一个自定义函数allow_access:

跟进分析可知,这个函数先获取了request和request_path,接着将 request_path 根据 / 进行分割,得到path_list,并提取path_list中的第二个元素作为path_base,再去从 path_perms_map 中通过 path_base 获取对应的 path_perm值。如果path_list长度不大于 1,则将 path_base 设置为 None。接着就是通过path_perm值进行权限验证了:

(1)如果 path_perm 为空,返回 False,禁止访问文件;
(2)如果 path_perm 等于 '*',说明该路径对应的文件允许任何用户访问,或者用户拥有指定的权限;
(3)如果 path_perm 等于 'default',说明只允许已认证用户访问;
(4)如果以上条件都不满足,则说明用户必须拥有指定的权限才能访问文件,直接返回False。

所以我们最需要关注的就是,能够将path_perm 值等于 '*'的字符串,这里提供了两个:’xpack’和’settings’。那么攻击者就可以通过/xpack/../或/settings/../绕过权限校验,最终实现目录权限绕过下载录像文件。当然这里的自定义函数校验的是静态文件,而静态文件显然不止录像文件。也就是说,攻击者可以通过这种方式获取全站静态文件。

参考demo如下:

漏洞复现

首先获取seesion信息:

接着下载相应录像文件:

最后通过官方播放器还原操作记录即可:

修复方案

JumpServer已发布修复版本,https://github.com/jumpserver/jumpserver/releases/tag/v3.6.4

修复细节如下:

Git History中,已新增has_permission验证:

Git History中,验证了请求路径中是否存在跨目录行为:

产品支持

网宿云WAF已第一时间支持对该漏洞利用攻击的防护,并持续挖掘分析其他变种攻击方式和各类组件漏洞,第一时间上线防护规则,缩短防护“空窗期”。

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值