Retour aux mises à jour
UpdatedJul 30, 2026

CVE-2026-11374-check — Mis à jour !

Script de détection pour CVE-2026-11374

Partager

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 :

ProduitBuild affectéBuild corrigé
ADSelfService Plus≤ 65286529
RecoveryManager Plus≤ 63206321
M365 Manager Plus≤ 48164817
ADAudit Plus≤ 87028703

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_AFFECTED n'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_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.
  • 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

OptionDescription
targetsUn ou plusieurs host, host:port, ou https://host:port
-f, --targets-file FILELit les cibles depuis un fichier (une par ligne ; commentaires avec #)
--briefUne seule ligne alignée par cible, pratique pour scanner de nombreux hôtes
--jsonÉmet des résultats JSON structurés
--timeout SECSDélai d'attente par requête (défaut : 15)
--no-buildIgnore la requête supplémentaire de numéro de build lors d'un résultat positif
--no-colorDé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

VerdictSignification
POTENTIALLY_AFFECTEDProduit 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).
UNAFFECTEDLe 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).
INCONCLUSIVEUn 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

CodeSignification
0Aucune cible n'a retourné POTENTIALLY_AFFECTED
1Au moins une cible est POTENTIALLY_AFFECTED
2Erreur 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 sondeVerdict
en-têtes de nettoyage et un cookie connu d'un produit concernéPOTENTIALLY_AFFECTED
cookie de produit, pas de nettoyage, statut ≠ 400UNAFFECTED (autonome / non intégré)
pas de cookie de produit concerné, statut ≠ 400UNAFFECTED (pas l'un des quatre produits)
en-têtes de nettoyage mais cookie de produit non reconnuUNAFFECTED (ManageEngine, hors périmètre)
HTTP 400INCONCLUSIVE (probablement le verrou de limite de débit IAM ; voir Limitations)

Limitations

  • POTENTIALLY_AFFECTED n'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 400 peut ê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 renvoient HTTP 400 et le signal d'intégration est masqué. L'outil les signale comme INCONCLUSIVE ; 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 :

  1. 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.

  2. Vérifiez le format du ticket émis si vous pouvez vous connecter. Le cookie CUSTOM_SSO_TICKET n'est pas HttpOnly, 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.

  3. 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.

  4. Cherchez des tentatives d'exploitation. Sur l'hôte, serverOut_<date>.txt enregistre 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_EXCEEDED sur 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.

  5. 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.

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

Catégories