
CVE-2026-11374-check — Mis à jour !
Script de détection pour CVE-2026-11374
Script de détection de la précondition CVE-2026-11374 ManageEngine AD360
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.
Est-ce sûr à exécuter ?
Oui. Il est conçu pour une utilisation en production et en évaluation.
- Rien n'est exploité. La sonde envoie un ticket SSO invalide (
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. - Aucun changement d'état de la cible. Chaque requête est un simple
GET, et les seuls cookies affectés sont ceux jetables envoyés par l'outil. - Pas de force brute ni de résolution de session. L'outil ne tente pas la résolution active de ticket par horodatage qui prouverait l'exploitabilité ; cela relève de l'exploitation plutôt que de la détection, et sort du cadre ici (voir Limitations).
Ce que cet outil peut et ne peut pas vous dire
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 :
- Confirmer qu'un produit concerné accessible a le chemin de rejeu de cookie CustomSSO actif (c'est-à-dire qu'il est intégré à AD360), ce qui constitue la précondition d'exploitation de la CVE-2026-11374.
- Identifier lequel des quatre produits il s'agit, à partir du cookie de session spécifique au produit.
- Lire au mieux un numéro de build d'un actif comme indication. Ceci est disponible sur ADSelfService Plus, ADAudit Plus et M365 Manager Plus ; indisponible sur RecoveryManager Plus.
Ce qu'il ne peut pas faire :
- Distinguer le vulnérable du corrigé. Il n'existe aucun signal sûr, passif et non authentifié pour cela. Un résultat
POTENTIALLY_AFFECTEDsignifie 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. - Confirmer l'exploitabilité. Prouver qu'un hôte est réellement exploitable nécessite d'observer le format d'un ticket émis (un nombre à 13 chiffres est vulnérable, un UUID est corrigé, les deux nécessitant une visibilité authentifiée ou sur l'hôte), de lire localement
conf/product.conf, ou de résoudre activement un ticket en direct (une véritable exploitation, intentionnellement non implémentée ici). - Se fier entièrement à un numéro de build ADSelfService Plus inférieur au build corrigé. Le
?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.
Prérequis
Python 3.7+ et la bibliothèque requests. Installez avec pip install requests.
Utilisation
# 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.
Options
| 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) |
Exemples
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 :
$ ./cve_2026_11374_check.py https://host-b:8081 --json
[
{
"target": "https://host-b:8081",
"state": "potentially_affected",
"detail": "ADAudit Plus: AD360-integrated, CustomSSO replay path active - precondition met ...",
"product": "ADAudit Plus",
"build": { "build": "8530", "fixed_build": "8703", "patch_hint": "inconclusive", "note": "below fixed 8703 - inconclusive: may be a hotfix" },
"verdict": "POTENTIALLY_AFFECTED"
}
]
Verdicts
| Verdict | Signification |
|---|---|
POTENTIALLY_AFFECTED | Produit concerné intégré à AD360 ; le chemin de rejeu de cookie CustomSSO est actif, donc la précondition d'exploitation de la CVE-2026-11374 est remplie. Ce n'est pas un verdict de vulnérabilité confirmée ; vérifiez le niveau de correctif (voir les étapes suivantes). |
UNAFFECTED | Le chemin de rejeu n'est pas accessible. Soit un produit concerné autonome (non intégré à AD360 — même s'il deviendrait accessible s'il était intégré plus tard, donc vérifiez le build quand même) ; soit un produit du framework ADS de ManageEngine qui ne fait pas partie des quatre concernés ; soit aucun produit concerné dans la réponse (pas l'un des quatre produits de la CVE-2026-11374, ou un proxy qui supprime le cookie de session). |
INCONCLUSIVE | Un HTTP 400 — probablement le verrou de limite de débit IAM qui masque le signal ; réessayez après ~60 s. |
ERROR | Échec de connexion/délai d'attente/TLS. |
Codes de sortie
| Code | Signification |
|---|---|
0 | Aucune cible n'a retourné POTENTIALLY_AFFECTED |
1 | Au moins une cible est POTENTIALLY_AFFECTED |
2 | Erreur d'utilisation (mauvais arguments / fichier de cibles illisible) |
Comment ça fonctionne
Envoyez un ticket invalide ainsi qu'une balise d'application à toute URL CustomSSO (*.do) :
GET /AppsHome.do
Cookie: CUSTOM_SSO_TICKET=1700000000000; CUSTOM_SSO_APP_TAG_NAME=AD360
Sur une installation intégrée à AD360, la chaîne ADSFilter → CustomSSOFilter → CookieSSOImpl exécute sa branche de résolution (la balise désigne un produit différent, donc appName != prodName), ne parvient pas à résoudre le faux ticket et émet des en-têtes de réponse de nettoyage des cookies :
Set-Cookie: CUSTOM_SSO_TICKET=removed; Max-Age=0; ...
Set-Cookie: CUSTOM_SSO_APP_NAME=removed; Max-Age=0; ...
Set-Cookie: CUSTOM_SSO_APP_TAG_NAME=removed; Max-Age=0; ...
Une installation autonome n'exécute jamais ce chemin et n'émet aucun nettoyage. Le produit est identifié via son cookie de session Tomcat fixe par produit (JSESSIONIDADSSP pour ADSelfService Plus, et ainsi de suite), défini sur chaque réponse. La vérification se base sur les en-têtes plutôt que sur le code de statut, car un ADSSP intégré renvoie un 302 tandis qu'ADAudit, M365 et RMP renvoient 200 à la même sonde.
| Réponse de la sonde | Verdict |
|---|---|
| en-têtes de nettoyage et un cookie connu d'un produit concerné | POTENTIALLY_AFFECTED |
| cookie de produit, pas de nettoyage, statut ≠ 400 | UNAFFECTED (autonome / non intégré) |
| pas de cookie de produit concerné, statut ≠ 400 | UNAFFECTED (pas l'un des quatre produits) |
| en-têtes de nettoyage mais cookie de produit non reconnu | UNAFFECTED (ManageEngine, hors périmètre) |
HTTP 400 | INCONCLUSIVE (probablement le verrou de limite de débit IAM ; voir Limitations) |
Limitations
POTENTIALLY_AFFECTEDn'est pas une « vulnérabilité confirmée ». C'est la précondition d'exploitation. Comme le correctif n'a pas touché ce chemin de code, un build corrigé répond de manière identique ; vous devez donc confirmer le niveau de correctif hors bande (voir les étapes suivantes). C'est la limite de ce qu'un observateur non authentifié peut savoir.- Pas de confirmation active. L'outil n'essaie jamais de résoudre un ticket réel à l'heure actuelle. Cette technique peut prouver positivement qu'un hôte est vulnérable, mais il s'agit d'une exploitation active (elle détourne une session en direct), elle est limitée par le débit et probabiliste, et elle nécessite une session victime active ; elle est donc exclue de ce détecteur.
- Un
HTTP 400peut être un verrou de limite de débit plutôt qu'une vraie réponse. Zoho IAM applique un limiteur de débit glissant par URL qui plafonne une IP source à environ 40 requêtes par 60 s, puis verrouille ce chemin pendant ~60 s. Pendant un verrouillage, les requêtes renvoientHTTP 400et le signal d'intégration est masqué. L'outil les signale commeINCONCLUSIVE; réessayez depuis cette IP après environ une minute. - Derrière un proxy inverse, une console qui supprime ou réécrit le cookie de session peut être signalée à tort comme
UNAFFECTED. Confirmez directement si vous attendez un produit ManageEngine à cet endroit. - Les numéros de build sont des indications, pas des verdicts. ADAudit (
?v=) et M365 (?bN=) exposent toujours le vrai build ; le?build=d'ADSSP est parfois réel et parfois un espace réservé figé qui affiche une valeur inférieure au build corrigé, donc une valeur ADSSP inférieure au corrigé est ambiguë ; RMP n'en expose aucun. Dans tous les cas, un build égal ou supérieur au build corrigé indique fortement un correctif, et une valeur inférieure est non concluante.
Prochaines étapes pour les défenseurs
Si une cible revient POTENTIALLY_AFFECTED, considérez-la comme exposée et méritant confirmation, puis :
-
Confirmez directement le niveau de correctif (l'outil ne le peut pas). Lisez
conf/product.conf(build_number) sur l'hôte et comparez-le au build corrigé pour ce produit (ADSelfService Plus 6529, RecoveryManager Plus 6321, M365 Manager Plus 4817, ADAudit Plus 8703). Interprétez-le de manière directionnelle : un build égal ou supérieur au build corrigé est un indicateur fort que l'hôte est corrigé, car le correctif UUID se trouve dans cette arborescence. Un build inférieur au build corrigé est non concluant plutôt qu'une preuve de vulnérabilité, car des correctifs à chaud et des rétroportages hors bande peuvent appliquer le correctif UUID sans augmenter le numéro de build ; dans ce cas, revenez à la vérification du format de ticket ci-dessous. -
Vérifiez le format du ticket émis si vous pouvez vous connecter. Le cookie
CUSTOM_SSO_TICKETn'est pasHttpOnly, donc après authentification vous pouvez lire sa valeur : un nombre à 13 chiffres signifie vulnérable, un UUID signifie corrigé. C'est la vérification positive la plus claire. -
Mettez à jour vers le build corrigé (ou ultérieur) sur tout hôte vulnérable ou dont vous ne pouvez pas confirmer qu'il est corrigé. Le correctif remplace le ticket prévisible par un UUID aléatoire.
-
Cherchez des tentatives d'exploitation. Sur l'hôte,
serverOut_<date>.txtenregistre le limiteur de débit comme des rafales de :IAMSecurityException ErrorCode: URL_ROLLING_THROTTLES_LIMIT_EXCEEDED, RequestURI: "/showLogin.cc", RemoteAddr: <source IP>Un pic de
URL_ROLLING_THROTTLES_LIMIT_EXCEEDEDsur les chemins de répartition SSO/connexion depuis une seule IP source est un indicateur fort de force brute sur les tickets. Examinez également les connexions réussies récentes et l'activité des sessions pour détecter des signes de prise de contrôle. -
Réduisez l'exposition entre-temps. Restreignez l'accès réseau à la suite AD360 (elle ne devrait pas être exposée à Internet), et si le chemin de rejeu n'est pas nécessaire, désactiver l'intégration CustomSSO supprime entièrement la précondition.
Remédiation
Mettez à jour le produit affecté vers au moins le build corrigé (ADSelfService Plus 6529, RecoveryManager Plus 6321, M365 Manager Plus 4817, ADAudit Plus 8703) ou une version ultérieure. Le correctif remplace le ticket SSO prévisible System.currentTimeMillis() par UUID.randomUUID().
Licence
Ce code est distribué sous la licence MIT.
Avertissement légal
L'utilisation de cet outil pour attaquer des cibles sans consentement mutuel préalable est illégale. Il est de la responsabilité de l'utilisateur final de respecter toutes les lois locales, nationales et fédérales applicables. Les développeurs déclinent toute responsabilité et ne sont pas responsables des mauvais usages ou des dommages causés par ce programme.
Voir aussi
- NVD: CVE-2026-11374
- Packs de service ManageEngine : ADSelfService Plus · RecoveryManager Plus · M365 Manager Plus · ADAudit Plus
- Bishop Fox Blog : Analyse technique complète