
Script de détection pour CVE-2026-11374
Un script de détection pour la précondition d'exploitation de la CVE-2026-11374, une faille prévisible de ticket SSO qui permet une prise de contrôle de compte non authentifiée sur l'ensemble de la suite ManageEngine AD360. Les quatre produits concernés partagent le ManageEngineADSFramework :
| Produit | Build affecté | Build corrigé |
|---|---|---|
| ADSelfService Plus | ≤ 6528 | 6529 |
| RecoveryManager Plus | ≤ 6320 | 6321 |
| M365 Manager Plus | ≤ 4816 | 4817 |
| ADAudit Plus | ≤ 8702 | 8703 |
Dans les builds affectés, le ticket SSO est simplement System.currentTimeMillis() (un horodatage prévisible) échantillonné lors de la connexion de la victime, et peut donc être rejoué via le cookie CUSTOM_SSO_TICKET pour détourner cette session. Le correctif remplace le ticket par UUID.randomUUID() (un identifiant suffisamment aléatoire). Le chemin de rejeu n'est accessible que lorsque le produit est intégré à AD360 : ADSFilter le conditionne via isProductIntegrated(). C'est cette condition que l'outil vérifie.
REMARQUE : ce détecteur confirme la précondition, pas la vulnérabilité elle-même. Un résultat
POTENTIALLY_AFFECTEDn'est pas un verdict de vulnérabilité confirmée — voir ci-dessous pour plus d'informations.
Oui. Il est conçu pour une utilisation en production et en évaluation.
1700000000000, une valeur en millisecondes suffisamment passée pour ne jamais être résidente en cache), donc aucune session n'est jamais récupérée. Le serveur nous demande simplement de supprimer les cookies que nous avons envoyés.GET, et les seuls cookies affectés sont ceux jetables envoyés par l'outil.Le correctif de la CVE-2026-11374 n'a modifié que la façon dont le ticket est généré (de millisecondes à UUID) ; il n'a pas changé le chemin de rejeu de cookie que cette sonde exerce. Par conséquent, une installation corrigée répond octet pour octet de manière identique à une installation vulnérable pour toute requête non authentifiée.
Ce que l'outil peut faire, sans authentification et de manière non destructive :
Ce qu'il ne peut pas faire :
POTENTIALLY_AFFECTED signifie que la précondition est remplie et que vous devez vérifier le niveau de correctif, pas que l'hôte est confirmé vulnérable.conf/product.conf, ou de résoudre activement un ticket en direct (une véritable exploitation, intentionnellement non implémentée ici).?build= d'ADSSP est parfois le vrai build et parfois un espace réservé figé qui affiche une valeur inférieure au build corrigé ; une valeur inférieure est donc ambiguë et l'outil la marque comme non concluante. Une valeur égale ou supérieure au build corrigé reste un signal fiable de correctif, car l'espace réservé est toujours trop bas pour l'atteindre.Python 3.7+ et la bibliothèque requests. Installez avec pip install requests.
# single host (prefer a URL or host:port; ports differ per product)
./cve_2026_11374_check.py https://adssp.example.com:8888
# multiple hosts (scheme optional: https is tried first, then http)
./cve_2026_11374_check.py host-a:8081 host-b:8365
# scan a list, one target per line ('#' comments allowed), compact output
./cve_2026_11374_check.py -f targets.txt --brief
# machine-readable output for pipelines
./cve_2026_11374_check.py -f targets.txt --json > results.json
Les ports par défaut diffèrent selon le produit (ADSelfService Plus 8888, ADAudit Plus 8081, M365 Manager Plus 8365, RecoveryManager Plus 8090), donc transmettez une URL ou host:port. Un hôte seul utilise par défaut le port 8888.
| Option | Description |
|---|---|
targets | Un ou plusieurs host, host:port, ou https://host:port |
-f, --targets-file FILE | Lit les cibles depuis un fichier (une par ligne ; commentaires avec #) |
--brief | Une seule ligne alignée par cible, pratique pour scanner de nombreux hôtes |
--json | Émet des résultats JSON structurés |
--timeout SECS | Délai d'attente par requête (défaut : 15) |
--no-build | Ignore la requête supplémentaire de numéro de build lors d'un résultat positif |
--no-color | Désactive la sortie colorée (respecte aussi NO_COLOR et les environnements non-TTY) |
Une console intégrée AD360 (mode verbeux, par défaut). La deuxième ligne précise qu'il s'agit de la précondition et non d'un verdict de vulnérabilité ; la troisième est l'indication de build au mieux :
$ ./cve_2026_11374_check.py https://adssp.example.com:8888
[!] https://adssp.example.com:8888: POTENTIALLY_AFFECTED
ADSelfService Plus: AD360-integrated, CustomSSO replay path active - precondition met. Not confirmed vulnerable; verify patch level (fixed build 6529).
build: 6519 (below fixed 6529 - inconclusive: ?build= may be a stale placeholder or a hotfix)
Une installation autonome du même produit, où le chemin de rejeu n'est pas actif :
$ ./cve_2026_11374_check.py https://adssp.example.com:8888
[+] https://adssp.example.com:8888: UNAFFECTED
ADSelfService Plus: standalone / not AD360-integrated (no cleanup), so the replay path isn't reachable here. Verify build >= 6529 regardless.
Analyse d'une liste avec une ligne alignée par hôte (--brief). Le code de sortie est 1 si au moins un hôte est POTENTIALLY_AFFECTED, sinon 0, ce qui est pratique dans les scripts. La note finale indique le produit identifié, ainsi que le numéro de build en cas de résultat positif :
$ ./cve_2026_11374_check.py -f targets.txt --brief; echo "exit: $?"
POTENTIALLY_AFFECTED https://host-a:8888 ADSelfService Plus 6519
POTENTIALLY_AFFECTED http://host-b:8081 ADAudit Plus 8530
UNAFFECTED http://host-c:8365 M365 Manager Plus
UNAFFECTED https://host-d:443
INCONCLUSIVE http://host-e:8888 ADSelfService Plus
ERROR host-f:8888 timeout
exit: 1
Sortie lisible par machine (--json). Chaque résultat contient le verdict, l'state et le detail correspondants, le product identifié, et — en cas de résultat positif — un objet build : build est le numéro trouvé, fixed_build le seuil pour ce produit, patch_hint l'indication directionnelle (likely_patched au niveau ou au-dessus du build corrigé, sinon inconclusive), et note une courte explication :