问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
JumpServer 未授权接口 远程命令执行漏洞
# JumpServer 未授权接口 远程命令执行漏洞 ## 漏洞描述 JumpServer 是全球首款完全开源的堡垒机, 使用GNU GPL v2.0 开源协议, 是符合4A 的专业运维审计系统。 JumpServer 使用Python / D...
JumpServer 未授权接口 远程命令执行漏洞 ========================= 漏洞描述 ---- JumpServer 是全球首款完全开源的堡垒机, 使用GNU GPL v2.0 开源协议, 是符合4A 的专业运维审计系统。 JumpServer 使用Python / Django 进行开发。2021年1月15日,阿里云应急响应中心监控到开源堡垒机JumpServer发布更新,修复了一处远程命令执行漏洞。由于 JumpServer 某些接口未做授权限制,攻击者可构造恶意请求获取到日志文件获取敏感信息,或者执行相关API操作控制其中所有机器。 漏洞影响 ---- JumpServer < v2.6.2 JumpServer < v2.5.4 JumpServer < v2.4.5 JumpServer = v1.5.9 网络测绘 ---- app="FIT2CLOUD-JumpServer-堡垒机" 环境搭建 ---- 安装 JumpServer v2.6.1 版本 [下载链接](https://www.o2oxy.cn/wp-content/uploads/2021/01/quick_start.zip) 安装注意 配置网络,配置Mysql,配置Redis 选择 n 等待完成安装执行以下命令 ```shell cd /opt/jumpserver-installer-v2.6.1 ./jmsctl.sh start ``` 等待安装完毕访问 <http://xxx.xxx.xxx.xxxx:8080> 默认账号密码 amdin:admin 漏洞复现 ---- 进入后台添加配置 `资产管理 --> 系统用户` ![img](https://shs3.b.qianxin.com/butian_public/f69145388a2f39a29593e0f13dbc3728e3606af019bfd.jpg) `资产管理 --> 管理用户` ![img](https://shs3.b.qianxin.com/butian_public/f76332779857d9fc67611f9e4cd25809794bc65b32752.jpg) `用户管理 --> 用户列表` ![img](https://shs3.b.qianxin.com/butian_public/f5264018880b8643a05b6870bac70499b0d72e343bbd5.jpg) `资产管理 --> 资产列表` ![img](https://shs3.b.qianxin.com/butian_public/f3925128565e50fd4215894934a145c5e5c6e4b349aa2.jpg) 查看一下项目代码提交变动 ![img](https://shs3.b.qianxin.com/butian_public/f341950a28103e5dbfc45786f9671d432b61a83bb2d83.jpg) ```python import time import os import threading import json from common.utils import get_logger from .celery.utils import get_celery_task_log_path from channels.generic.websocket import JsonWebsocketConsumer logger = get_logger(__name__) class CeleryLogWebsocket(JsonWebsocketConsumer): disconnected = False def connect(self): user = self.scope["user"] if user.is_authenticated and user.is_org_admin: self.accept() else: self.close() def receive(self, text_data=None, bytes_data=None, **kwargs): data = json.loads(text_data) task_id = data.get("task") if task_id: self.handle_task(task_id) def wait_util_log_path_exist(self, task_id): log_path = get_celery_task_log_path(task_id) while not self.disconnected: if not os.path.exists(log_path): self.send_json({'message': '.', 'task': task_id}) time.sleep(0.5) continue self.send_json({'message': '\r\n'}) try: logger.debug('Task log path: {}'.format(log_path)) task_log_f = open(log_path, 'rb') return task_log_f except OSError: return None def read_log_file(self, task_id): task_log_f = self.wait_util_log_path_exist(task_id) if not task_log_f: logger.debug('Task log file is None: {}'.format(task_id)) return task_end_mark = [] while not self.disconnected: data = task_log_f.read(4096) if data: data = data.replace(b'\n', b'\r\n') self.send_json( {'message': data.decode(errors='ignore'), 'task': task_id} ) if data.find(b'succeeded in') != -1: task_end_mark.append(1) if data.find(bytes(task_id, 'utf8')) != -1: task_end_mark.append(1) elif len(task_end_mark) == 2: logger.debug('Task log end: {}'.format(task_id)) break time.sleep(0.2) task_log_f.close() def handle_task(self, task_id): logger.info("Task id: {}".format(task_id)) thread = threading.Thread(target=self.read_log_file, args=(task_id,)) thread.start() def disconnect(self, close_code): self.disconnected = True self.close() ``` 新版对用户进行了一个判断,可以使用 谷歌插件 WebSocket King 连接上这个websocket 进行日志读取 ![img](https://shs3.b.qianxin.com/butian_public/f8955762e8956acaa3961ecc4e685c2bec2dbd0e2f8c6.jpg) 比如send这里获取的 Task id ,这里是可以获得一些敏感的信息的 ![img](https://shs3.b.qianxin.com/butian_public/f4075511109fa49befc75dbae3fc936ed0b71630a3f2f.jpg) 查看一下连接Web终端的后端api代码 ![img](https://shs3.b.qianxin.com/butian_public/f9419550705006dd5f3c5952409ffc4eeefa63f254915.jpg) 可以看到这里调用时必须需要 `user asset system_user` 这三个值,再获取一个20秒的 `token` 访问web终端后查看日志的调用 ![img](https://shs3.b.qianxin.com/butian_public/f8185331cbec84e78e5fba697f56fcac5e1d1d406e9d6.jpg) ```plain docker exec -it (jumpserve/core的docker) /bin/bash cat gunicorn.log | grep /api/v1/perms/asset-permissions/user/validate/? ``` ![img](https://shs3.b.qianxin.com/butian_public/f755977ba6ab1979def8e3ac39f1c1a3cde966e3bb799.jpg) ```plain assset_id=ee7e7446-6df7-4f60-b551-40a241958451 system_user_id=d89bd097-b7e7-4616-9422-766c6e4fcdb8 user_id=efede3f4-8659-4daa-8e95-9a841dbe82a8 ``` 可以看到在不同的时间访问这个接口的asset\_id等都是一样的,所以只用在 `刚刚的未授权日志读取`里找到想要的这几个值就可以获得 token ![img](https://shs3.b.qianxin.com/butian_public/f4831620e2aaabc7f12614e8f71e644802967cab94318.jpg) 发送请求获取20s的token ![img](https://shs3.b.qianxin.com/butian_public/f591913cb1d7db75c1bf72f444e48513b227fc3229af4.jpg) 看一下 koko.js 这个前端文件 ![img](https://shs3.b.qianxin.com/butian_public/f34777789ef51696f0beb4b771a337b7d2ede2a95f55a.jpg) <br/> 后端代码 <https://github.com/jumpserver/koko/blob/e054394ffd13ac7c71a4ac980340749d9548f5e1/pkg/httpd/webserver.go> ![img](https://shs3.b.qianxin.com/butian_public/f1836432d7a6598d0c8cf67e1937dd2f10a97cc07d1a6.jpg) 这里我们就可以通过 获得的token来模拟请求 ![img](https://shs3.b.qianxin.com/butian_public/f3605180d8da52dcff150b35040925353526853c087b6.jpg) 成功连接模拟了这个 token 的请求,可以在Network看一下流量是怎么发送的 ![img](https://shs3.b.qianxin.com/butian_public/f938310dd603e3191313fe99b3dbac2fa40724ccbd229.jpg) 模拟连接发送和接发数据 ![img](https://shs3.b.qianxin.com/butian_public/f947155902477036f98a68a3d4a29769812d69bfeed06.jpg) 这里可以看到我们只要模拟了这个发送,返回的数据和web终端是一样的,那我们就可以通过这样的方法来进行命令执行了
发表于 2024-07-12 18:46:17
阅读 ( 986 )
分类:
Web应用
0 推荐
收藏
0 条评论
请先
登录
后评论
带头大哥
456 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!