Threat Intelligence

CVE-2025-25249 : le débordement de tas du démon CAPWAP de FortiGate qui livre PivotC2 aux réseaux internes

Admin CyberAfrik 11 September 2026 21 lectures
CVE-2025-25249 : le débordement de tas du démon CAPWAP de FortiGate qui livre PivotC2 aux réseaux internes

Rapport CTI technique du 11 septembre 2026

Résumé exécutif

CVE-2025-25249 est un débordement de tas (CWE-122) dans le démon cw_acd de FortiOS et FortiSwitchManager, le processus qui traite le trafic CAPWAP servant à piloter les points d'accès sans fil. Le démon écoute sur le port UDP 5246 et n'exige aucune authentification préalable : une requête CAPWAP forgée suffit à corrompre la mémoire du processus et à obtenir l'exécution de code à distance. Fortinet a publié l'advisory FG-IR-25-084 le 13 janvier 2026, mais l'exploitation en conditions réelles n'a été confirmée avec un haut niveau de certitude que le 8 septembre 2026 par la SOCRadar Threat Research Unit, remontant à au moins juillet 2026. CISA a inscrit la faille à son catalogue KEV le 9 septembre 2026 avec une échéance de remédiation fédérale fixée au 12 septembre.

La charge finale s'appelle PivotC2 : un cheval de Troie d'accès distant écrit en Node.js, taillé spécifiquement pour la post-exploitation d'appliances FortiGate. Il maintient une connexion TLS sortante persistante vers son serveur de commande, ce qui contourne d'emblée les règles de pare-feu entrantes, et propose shells interactifs, tunneling SOCKS5 et HTTP, redirection de ports, scan de sous-réseaux et surtout une moisson automatisée des fichiers de configuration FortiGate avec déchiffrement des secrets ENC. Un mode --auto transforme chaque infection en pipeline autonome. Sur une liste de plus de 30 000 adresses IP visées, 178 appliances ont été confirmées infectées, la plus forte concentration aux États-Unis. SOCRadar attribue l'opération avec un haut niveau de confiance à un acteur cybercriminel russophone à motivation financière, distinct de l'opération FortiBleed.

Chronologie

DateÉvénement
13 janvier 2026Fortinet publie l'advisory FG-IR-25-084 et les correctifs pour CVE-2025-25249
Juillet 2026 (au plus tôt)Début de l'exploitation en conditions réelles observée par SOCRadar
8 septembre 2026SOCRadar (STRU) publie l'analyse de la campagne PivotC2, exploitation confirmée avec haut niveau de certitude
9 septembre 2026CISA ajoute CVE-2025-25249 au catalogue KEV
12 septembre 2026Échéance de remédiation fixée par CISA pour les agences fédérales civiles

Fiche vulnérabilité

CVE-2025-25249 | CVSS 9.8 (NVD) / 7.4 (Fortinet) | FortiOS et FortiSwitchManager, démon cw_acd (CAPWAP)

Débordement de tas dans le traitement des messages de contrôle CAPWAP. Le démon cw_acd gère le protocole CAPWAP (Control And Provisioning of Wireless Access Points) qui permet à un FortiGate d'administrer des points d'accès. Il valide mal la longueur de certaines données avant de les copier dans un tampon de taille fixe alloué depuis un pool mémoire interne (free_list_mp2). Un attaquant qui envoie une séquence de messages CAPWAP forgés sur UDP/5246 déclenche l'écrasement d'un nœud de liste chaînée adjacent, puis convertit cette corruption en primitive d'écriture arbitraire.

Conditions d'exploitation : accès réseau au port UDP 5246, aucun identifiant, aucune interaction utilisateur. L'outil récupéré cible spécifiquement 13 modèles FortiGate et 2 modèles FortiAP sous FortiOS 7.4 (builds 7.4.0 à 7.4.8), donc l'exposition immédiate en conditions réelles se concentre sur cette plage, même si le périmètre des versions affectées est plus large.

Versions affectées : FortiOS 7.6.0-7.6.3, 7.4.0-7.4.8, 7.2.0-7.2.11, 7.0.0-7.0.17, 6.4 (toutes) ; FortiSwitchManager 7.2.0-7.2.6 et 7.0.0-7.0.5.

PoC disponible : pas de PoC public générique, mais un outil d'exploitation complet (fortirun.bin) a été récupéré et documenté par SOCRadar, avec les primitives de fingerprinting, contournement d'ASLR, heap grooming et hijack du flux d'exécution.

Patch/mitigation : mettre à jour vers FortiOS 7.6.4, 7.4.9, 7.2.12, 7.0.18 ou supérieur, et FortiSwitchManager 7.2.7 ou 7.0.6 ou supérieur. À défaut, désactiver le service fabric sur les interfaces externes ou appliquer une politique local-in qui rejette le trafic UDP entrant sur les ports CAPWAP Control (5246-5249), conformément à FG-IR-25-084.

Diagramme de la chaîne d'attaque

Chaîne d'attaque CVE-2025-25249 vers PivotC2

Infrastructure et capacités de la campagne PivotC2 après exploitation de CVE-2025-25249. Sources : SOCRadar STRU, Fortinet FG-IR-25-084.

Analyse technique

Étape 1 : fingerprinting et contournement d'ASLR

fortirun.bin est un framework d'exploitation à deux étages compilé en ELF x86-64. À l'exécution, il décompresse une charge Zstandard stockée dans sa section .rodata : un interpréteur CPython complet et un binaire interne portant deux modules Python compilés, fortipwn.py et fortirun.py. L'exploit envoie d'abord des paquets CAPWAP Discovery Request avec une adresse MAC aléatoire. La réponse de l'Access Controller expose deux champs, hw_rev (révision matérielle) et sw_ver (version firmware, du type FGT60F-v7.4-build2731). Ces identifiants sont croisés avec une table de compatibilité codée en dur couvrant les 15 modèles ciblés. La réponse Discovery fuite en prime des pointeurs mémoire vivants, ce qui permet à fortipwn.py de recalculer image_base et data_rw_base au runtime. L'ASLR, censé rendre les adresses imprévisibles à chaque démarrage, tombe donc dès la phase de reconnaissance.

Étape 2 : heap grooming du pool free_list_mp2

Le démon cw_acd sert ses petites allocations depuis free_list_mp2, une liste doublement chaînée de chunks de taille fixe dont chaque nœud porte deux pointeurs fd (suivant) et bk (précédent). L'exploit envoie en boucle des messages CAPWAP Add Station, normalement émis quand un client sans fil s'associe à un point d'accès. Chaque paquet forgé transporte un descripteur de station rempli de 56 octets de 0x41, ce qui force l'allocation d'un chunk de 72 octets (56 de données plus 16 d'overhead). En saturant les trous du pool, l'attaquant range les chunks suivants dans des adresses contiguës et prévisibles, jusqu'à placer son tampon contrôlé immédiatement avant le nœud free_list_mp2 qu'il veut corrompre.

Étape 3 : débordement et écriture arbitraire

Une fois le tas préparé, l'exploit envoie un message CAPWAP Image Data (destiné aux mises à jour de firmware). Le paquet est construit avec le format struct <IIQQQQQ (48 octets) et embarque l'offset de la cible d'écriture, image_base, data_rw_base, l'adresse du nœud free_list_mp2, l'adresse d'un gadget de pivot ARM64 br x16 et l'adresse d'execvp. Les champs d'en-tête me_type et me_sz déclarent une taille inférieure à la donnée réellement écrite, ce qui pousse le démon à copier 16 octets au-delà du tampon de 56. Le débordement écrase fd et bk du nœud voisin. Lors de l'opération d'unlink qui retire le chunk de la liste, ces pointeurs falsifiés se transforment en primitive write-what-where, dans un style safe-unlink / House of Einherjar.

Étape 4 : hijack de flux via ROP et reverse shell Node.js

W^X (DEP) interdit l'exécution de code injecté sur le tas. L'exploit utilise donc du Return-Oriented Programming : le gadget br x16 sert de pivot pour rediriger le pointeur d'instruction vers execvp. L'appel execvp détourné lance un reverse shell Node.js. Ce choix n'est pas fortuit : FortiOS embarque nativement un runtime Node.js dans son plan de management, donc l'attaquant n'a rien à déposer de neuf sur le disque. Le module fortirun.py injecte ensuite la charge Node.js décodée en Base64 directement dans le REPL interactif (node -i), avec un marqueur de fin __FORTIPWN_DONE_ suivi de 16 caractères hexadécimaux aléatoires pour synchroniser la capture de sortie.

Étape 5 : PivotC2 et pillage autonome du réseau interne

Le stager Node.js télécharge un second étage (/tmp/.i.js), le décode en Base64 puis le déchiffre par XOR avec la clé pivot, et l'exécute en processus d'arrière-plan qui survit à la mort du parent. C'est PivotC2 (version récupérée 0.2.3). Il ouvre une connexion TLS sortante multiplexée sur un protocole de framing binaire inspiré des canaux SSH. Ses commandes couvrent exec, harvest, portscan, dns, listen, plus des canaux shell, upload, download, direct (proxy SOCKS5/HTTP) et forward (redirection inverse). Lancé avec --auto, le serveur C2 déroule pour chaque nouvelle victime un pipeline en cinq temps : handshake HELLO, moisson des configurations, déchiffrement des identifiants, extraction des interfaces internes, puis scan de ports (22, 80, 389, 443, 445, 902, 1433, 3389, 5432) sur les sous-réseaux découverts et une liste prédéfinie (10.0.0.0/24, 10.0.1.0/24, 172.16.0.0/24, 192.168.0.0/24, 192.168.1.0/24). La moisson vise /data/config/sys_global.conf.gz, global_system_interface.gz, la config VDOM avec les hachés ENC, et /data/etc/fsv_sync.dat qui contient la clé AES-128-GCM du device. Le déchiffrement combine AES-256-CBC (clé codée en dur, repérée au trailer magique Yf267vE@) et AES-128-GCM dérivée du device, ce qui restitue en clair les PSK VPN, les identifiants SSL-VPN, les PSK Wi-Fi, les binds LDAP et les comptes administrateur. Ces secrets sont réutilisables partout ailleurs dans le SI, ce qui explique le mouvement latéral observé sur deux victimes américaines (activation RDP, relais reverse-SSH via russh, vol de credentials navigateur, exfiltration de .pst vers des buckets S3 Wasabi).

Indicateurs de compromission

TypeValeur
IP (C2 PivotC2)46.151.29.58
IP (C2 PivotC2)146.103.99.177
IP:port (bridge TOR obfs4)45.138.16.182:9130
IP:port (bridge TOR obfs4)89.217.174.207:9001
SHA256 (fortirun.bin)2d338ffc8cc80293575c6800c059e33eb41e967907c20ba7687b2231c50837db
SHA256 (payload.js, stager)cc7f0660d56405cbdff157033d3e35305f063e62efaff6501d11e6a34e7bd151
SHA256 (client PivotC2 décodé, 146.103.99.177:8443)550f99193f9e90d93b70af1ab050a2d44f1830259ea165568dafc518e761c589
SHA256 (run.ps1, injection de processus)c25a27b506fbae62010caf2abff699df5c94d29f056fa7ccfb5f3170d917c8cb
Artefact hôte/tmp/.i.js (charge PivotC2 stagée)
Clé XOR stagerpivot
Marqueur RDP registrefDenyTSConnections=0, DisableRestrictedAdmin=0

MITRE ATT&CK

Cartographie fournie par SOCRadar dans son analyse (extraits représentatifs de la chaîne).

TactiqueTechniqueIDJustification
Resource DevelopmentDevelop Capabilities: ExploitsT1587.004Développement de fortirun.bin pour CVE-2025-25249
Initial AccessExploit Public-Facing ApplicationT1190Exploitation du démon CAPWAP sur FortiGate exposé
ExecutionCommand and Scripting Interpreter: JavaScriptT1059.007Exécution de PivotC2 via le runtime Node.js embarqué
Defense EvasionObfuscated Files or InformationT1027Base64 et XOR (clé pivot) sur le stager et le client
DiscoveryNetwork Service DiscoveryT1046Scans de ports auto-mode sur CIDR internes
CollectionUnsecured Credentials: Credentials In FilesT1552.001Moisson et déchiffrement des secrets ENC FortiGate
Lateral MovementRemote Services: SSHT1021.004Relais reverse-SSH russh en interne
Command and ControlEncrypted Channel: Asymmetric CryptographyT1573.002Socket TLS unique avec certificate pinning
ExfiltrationExfiltration to Cloud StorageT1567.002Envoi de .pst Exchange vers buckets S3 Wasabi

Remédiation : checklist opérationnelle

  1. Mettre à jour FortiOS vers 7.6.4 / 7.4.9 / 7.2.12 / 7.0.18 (ou supérieur) et FortiSwitchManager vers 7.2.7 / 7.0.6 (ou supérieur).
  2. Réduire la surface : désactiver le service fabric sur les interfaces externes ou poser une politique local-in bloquant l'UDP entrant sur les ports CAPWAP 5246-5249.
  3. Chasser les sessions actives vers les C2 connus : diagnose sys session filter daddr 146.103.99.177 puis diagnose sys session list, idem pour 46.151.29.58.
  4. Auditer le système de fichiers : fnsysctl ls -la /tmp/.i.js et fnsysctl ls -la /tmp/.
  5. Chercher l'exécution Node.js anormale : diagnose sys process list | grep node (le nom de processus seul n'est pas fiable, Node.js étant légitime sous FortiOS).
  6. Si des artefacts sont trouvés, traiter la configuration entière comme exfiltrée : faire tourner tous les mots de passe administrateur, identifiants SSL-VPN, secrets de bind LDAP, PSK Wi-Fi et pre-shared keys IPSec.
  7. Considérer l'appliance comme un point de pivot : passer en revue les hôtes internes pour les modifications RDP en registre, les relais reverse-SSH, les accès aux credentials navigateur et les transferts sortants vers du stockage cloud.
  8. Ne pas se contenter du patch : il ferme le vecteur mais ne retire ni l'implant déjà en cours d'exécution ni les identifiants déjà moissonnés. Toute appliance avec artefacts confirmés doit être reconstruite depuis un état sain, suivie d'une rotation complète des secrets.

Sources

Tags : CVE-2025-25249FortiGateFortiOSCAPWAPPivotC2RAT Node.jsKEV CISAexploitation active
Partager cet article