T0ngMystic`s Blog

"Security studying, Strive to be Security Re-Searcher. Love everything that I want to do"

CVE-2023-42442-Jumpserver身份绕过获取会话回放(2)

image

2023-10-03 / 共计1468 字


CVE-2023-42442-Jumpserver身份绕过获取会话回放(2)

以喜欢之心,慢度日常。

be fondness heart to slowly live life.

祝大家2023年中秋国庆快乐,为庆祝中秋国庆那就把先前挖下的坑给填上(自己也没想到这么快就给填了)。

漏洞复现

POC已于 2023-09-27 2023-10-01添加会话获取功能,发布于github有需要的朋友自取(CVE-2023-42442-JumpServer

poc:

/media/xpack/../replay/" + {time} + "/" + {id} + ".cast.gz

首先通过接口/api/v1/terminal/sessions/获取到的会话相关信息(可见 CVE-2023-42442-Jumpserver身份绕过),再调用该接口可查看会话下所执行的命令及结果: image.png POC如何使用可见github(CVE-2023-42442-JumpServer

漏洞分析

首先通过路由表下找到了replay信息获取的一个接口: image.png 跟进SessionReplayViewSet获取到retrieve方法如下: image.png 既然这是获取回放的接口,那么Response中肯定与回放相关,所以继续跟进get_replay_data(从名字看也与回放有关)方法,可以看到data中有所有返回的数据,其中src即为回放下载的对应地址(我试出来的): image.png 由于url参数是传递进来的,那么还是需要回到get_replay_data方法中去找url是如何生成的,可以发现是storage.get_file_path_url方法,而storage是ReplayStorageHandler类的实体: image.png 从ReplayStorageHandler类其实就可以看到有多个获取存储路径的方法: image.png RepalyStorageHandler继承了BaseStorageHandler,BaseStorageHandler中每个获取路径的实现如下,不难发现最后返回的是replay/2021-12-08/session_id.cast.gz这样的数据: image.png 从ReplayStorageHandler类中的find_local得知,返回的url还经过了default_storage.url处理: image.png 作为Django项目从 terminal.models 导入 default_storage时,它是指向整个Django项目中的默认文件存储的引用,所以可以从配置文件中寻找MEDIA_URL 和 MEDIA_ROOT。配置文件中得知MEDIA_URL=‘/media/’。 再综上所述,前面的url = default.store.url(_local_path) 返回格式为/media/replay/2021-12-08/session_id.cast.gz

并且使用jumpserver.rewriting.storage.permissions.allow_access进行权限控制: image-CVE-2023-42442-jumpserver会话回放-20231001230643571 既然找到了权限控制的方法,那么肯定得进去看看。使用名为 path_perms_map 的字典来映射不同的路径(path_base)到相应的权限(path_perm)

image.png

通过分析上面的代码,得知只要path_perm == *,那么就有访问权限,由此就可以构造poc获取会话回放了,开头/media/进入静态目录,由于使用/分割url,并取第二个查看权限,xpack对应path_perm为*,/../回到media目录,后面的/replay/session_time/session_id.cast.gz的就是正常的回放访问url: /media/xpack/../replay/session_time/session_id.cast.gz image.png

文笔垃圾,技术欠缺,欢迎各位大师傅请斧正,非常感谢!


如果文章对您有帮助

部分文章会发布公众号!

感谢您的支持!