
Script di rilevamento per CVE-2026-11374
Uno script di rilevamento per la precondizione di sfruttamento di CVE-2026-11374, una falla del ticket SSO prevedibile che porta all'acquisizione non autenticata di account nell'intera suite ManageEngine AD360. I quattro prodotti interessati condividono il ManageEngineADSFramework:
| Prodotto | Build vulnerabile | Build corretta |
|---|---|---|
| ADSelfService Plus | ≤ 6528 | 6529 |
| RecoveryManager Plus | ≤ 6320 | 6321 |
| M365 Manager Plus | ≤ 4816 | 4817 |
| ADAudit Plus | ≤ 8702 | 8703 |
Nelle build vulnerabili, il ticket SSO è semplicemente System.currentTimeMillis() (un timestamp prevedibile) campionato al login della vittima, quindi può essere riutilizzato tramite il cookie CUSTOM_SSO_TICKET per dirottare la sessione. La correzione sostituisce il ticket con UUID.randomUUID() (un identificatore sufficientemente casuale). Il percorso di replay è raggiungibile solo quando il prodotto è integrato con AD360: ADSFilter lo vincola a isProductIntegrated(). Questa condizione è la precondizione che questo strumento verifica.
NOTA: questo rilevatore conferma la precondizione, non la vulnerabilità stessa. Un risultato
POTENTIALLY_AFFECTEDnon è un verdetto di vulnerabilità confermata — vedi sotto per maggiori informazioni.
Sì. È progettato per l'uso in produzione e per valutazioni.
1700000000000, un valore in millisecondi sufficientemente passato da non poter mai essere presente in cache), quindi non viene mai recuperata alcuna sessione. Il server ci dice solo di cancellare i cookie che abbiamo inviato.GET, e gli unici cookie coinvolti sono quelli usa-e-getta inviati dallo strumento.La patch di CVE-2026-11374 ha modificato solo il modo in cui viene generato il ticket (da millisecondi a UUID); non ha cambiato il percorso di cookie-replay che questa sonda esercita. Di conseguenza, un'installazione patchata risponde in modo identico byte-per-byte a una vulnerabile per qualsiasi richiesta non autenticata.
Cosa può fare lo strumento, senza autenticazione e in modo non distruttivo:
Cosa non può fare:
POTENTIALLY_AFFECTED significa che la precondizione è soddisfatta e dovresti verificare il livello di patch, non che l'host sia confermato vulnerabile.conf/product.conf localmente, o risolvere attivamente un ticket attivo (vera sfruttamento, volutamente non implementato qui).?build= di ADSSP a volte è la build reale e a volte un segnaposto congelato che riporta un valore inferiore alla build corretta, quindi un valore sotto la soglia è ambiguo e lo strumento lo segna come inconcludente. Un valore pari o superiore alla build corretta è comunque un segnale affidabile di patch, poiché il segnaposto è sempre troppo basso per raggiungerlo.requests. Installa con 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
Le porte predefinite variano a seconda del prodotto (ADSelfService Plus 8888, ADAudit Plus 8081, M365 Manager Plus 8365, RecoveryManager Plus 8090), quindi passa un URL o host:port. Un host semplice usa per impostazione predefinita 8888.
Una console integrata AD360 (verbose, l'impostazione predefinita). La seconda riga chiarisce che questa è la precondizione e non un verdetto di vulnerabilità; la terza è l'indicazione della build con il massimo sforzo possibile:
$ ./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)
Un'installazione standalone dello stesso prodotto, dove il percorso di replay non è attivo:
$ ./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.
Scansione di una lista con una riga allineata per host (--brief). Lo stato di uscita è 1 se un qualsiasi host risulta POTENTIALLY_AFFECTED, altrimenti 0, il che è comodo negli script. La nota finale mostra il prodotto identificato, più il numero di build in caso di riscontro:
$ ./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
Output leggibile da macchina (--json). Ogni risultato include il verdict, lo state e il detail sottostanti, il product identificato e — in caso di riscontro — un oggetto build: build è il numero trovato, fixed_build la soglia per quel prodotto, patch_hint la valutazione direzionale (likely_patched per valori pari o superiori alla build corretta, altrimenti inconclusive), e note una breve spiegazione:
$ ./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"
}
]
| Codice | Significato |
|---|---|
0 | Nessun target ha restituito POTENTIALLY_AFFECTED |
1 | Almeno un target risulta POTENTIALLY_AFFECTED |
2 |
Invia un ticket non valido più un tag applicazione a qualsiasi URL CustomSSO (*.do):
GET /AppsHome.do
Cookie: CUSTOM_SSO_TICKET=1700000000000; CUSTOM_SSO_APP_TAG_NAME=AD360
Su un'installazione integrata AD360, la catena ADSFilter → CustomSSOFilter → CookieSSOImpl esegue il suo ramo di risoluzione (il tag indica un prodotto diverso, quindi appName != prodName), non riesce a risolvere il ticket fittizio e emette header di risposta di pulizia dei cookie:
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; ...
Un'installazione standalone non esegue mai quel percorso e non emette alcuna pulizia. Il prodotto viene identificato dal suo cookie di sessione Tomcat fisso per prodotto (JSESSIONIDADSSP per ADSelfService Plus, e così via), che viene impostato in ogni risposta. Il controllo si basa sugli header piuttosto che sul codice di stato, poiché un ADSSP integrato restituisce un 302 mentre ADAudit, M365 e RMP restituiscono 200 alla stessa sonda.
POTENTIALLY_AFFECTED non è "vulnerabilità confermata". È la precondizione di sfruttamento. Poiché la patch non ha toccato questo percorso di codice, una build patchata risponde in modo identico, quindi devi confermare il livello di patch fuori banda (vedi i passaggi successivi). Questo è il limite massimo di ciò che un osservatore non autenticato può sapere.HTTP 400 può essere un blocco rate-limit piuttosto che una risposta reale. Zoho IAM applica un throttle scorrevole per URL che limita un IP sorgente a circa 40 richieste per 60 s, quindi blocca quel percorso per ~60 s. Durante un blocco, le richieste restituiscono HTTP 400 e il segnale di integrazione è mascherato. Lo strumento segnala questi casi come INCONCLUSIVE; riprova da quell'IP dopo circa un minuto.UNAFFECTED. Conferma direttamente se ti aspetti un prodotto ManageEngine lì.?v=) e M365 (?bN=) espongono sempre la build reale; il ?build= di ADSSP a volte è reale e a volte un segnaposto congelato che riporta un valore inferiore alla build corretta, quindi un valore ADSSP sotto la soglia è ambiguo; RMP non ne espone nessuno. In ogni caso, una build pari o superiore alla build corretta indica fortemente che la patch è applicata, mentre un valore inferiore è inconcludente.Se un target risulta POTENTIALLY_AFFECTED, trattalo come esposto e meritevole di conferma, poi:
Conferma direttamente il livello di patch (lo strumento non può). Leggi conf/product.conf (build_number) sull'host e confrontalo con la build corretta per quel prodotto (ADSelfService Plus 6529, RecoveryManager Plus 6321, M365 Manager Plus 4817, ADAudit Plus 8703). Interpretalo in modo direzionale: una build pari o superiore alla build corretta è un forte indicatore che l'host è patchato, poiché la correzione UUID è in quel ramo. Una build inferiore alla build corretta è inconcludente piuttosto che prova di vulnerabilità, perché hotfix e backport fuori banda possono applicare la correzione UUID senza aumentare il numero di build; in tal caso, affidati al controllo del formato del ticket descritto sotto.
Controlla il formato del ticket generato se puoi accedere. Il cookie CUSTOM_SSO_TICKET non è HttpOnly, quindi dopo l'autenticazione puoi leggerne il valore: un numero a 13 cifre significa vulnerabile, un UUID significa patchato. Questo è il controllo positivo più chiaro.
Aggiorna alla build corretta (o successiva) su qualsiasi host vulnerabile o di cui non puoi confermare la patch. La correzione sostituisce il ticket prevedibile con un UUID casuale.
Cerca tentativi di sfruttamento. Sull'host, serverOut_<date>.txt registra il throttling come raffiche di:
IAMSecurityException ErrorCode: URL_ROLLING_THROTTLES_LIMIT_EXCEEDED,
RequestURI: "/showLogin.cc", RemoteAddr: <source IP>
Un picco di URL_ROLLING_THROTTLES_LIMIT_EXCEEDED sui percorsi di dispatch SSO/login da un singolo IP sorgente è un forte indicatore di brute force sui ticket. Inoltre, esamina i login riusciti recenti e l'attività delle sessioni per individuare segni di takeover.
Aggiorna il prodotto interessato almeno alla build corretta (ADSelfService Plus 6529, RecoveryManager Plus 6321, M365 Manager Plus 4817, ADAudit Plus 8703) o successiva. La correzione sostituisce il ticket SSO prevedibile System.currentTimeMillis() con UUID.randomUUID().
Questo codice è distribuito sotto una licenza MIT.
L'uso di questo strumento per attaccare target senza previo consenso reciproco è illegale. È responsabilità dell'utente finale rispettare tutte le leggi locali, statali e federali applicabili. Gli sviluppatori non si assumono alcuna responsabilità e non sono responsabili per qualsiasi uso improprio o danno causato da questo programma.
| Flag | Descrizione |
|---|
targets | Uno o più host, host:port, o https://host:port |
-f, --targets-file FILE | Legge i target da un file (uno per riga; commenti #) |
--brief | Una singola riga allineata per target, utile per scansionare molti host |
--json | Emette risultati JSON strutturati |
--timeout SECS | Timeout per richiesta (predefinito: 15) |
--no-build | Salta la richiesta aggiuntiva del numero di build in caso di riscontro positivo |
--no-color | Disabilita l'output colorato (rispetta anche NO_COLOR e i non-TTY) |
| Verdetto | Significato |
|---|
POTENTIALLY_AFFECTED | Prodotto in scope integrato con AD360; il percorso di cookie-replay CustomSSO è attivo, quindi la precondizione di sfruttamento di CVE-2026-11374 è soddisfatta. Non è un verdetto di vulnerabilità confermata; verifica il livello di patch (vedi i passaggi successivi). |
UNAFFECTED | Il percorso di replay non è raggiungibile. Uno qualsiasi dei seguenti: un prodotto in scope standalone (non integrato con AD360 — anche se diventerebbe raggiungibile se integrato in seguito, quindi verifica comunque la build); un prodotto ManageEngine del framework ADS che non è uno dei quattro in scope; oppure nessun prodotto in scope nella risposta (non uno dei quattro prodotti CVE-2026-11374, o un proxy che rimuove il cookie di sessione). |
INCONCLUSIVE | Un HTTP 400 — probabilmente il blocco del rate-limit IAM che maschera il segnale; riprova dopo ~60 s. |
ERROR | Errore di connessione/timeout/TLS. |
| Errore di utilizzo (argomenti non validi / file dei target illeggibile) |
| Risposta della sonda | Verdetto |
|---|
| header di pulizia e cookie di un prodotto in scope noto | POTENTIALLY_AFFECTED |
| cookie di prodotto, nessuna pulizia, stato ≠ 400 | UNAFFECTED (standalone / non integrato) |
| nessun cookie di prodotto in scope, stato ≠ 400 | UNAFFECTED (non uno dei quattro prodotti) |
| header di pulizia ma cookie di prodotto non riconosciuto | UNAFFECTED (ManageEngine, non in scope) |
HTTP 400 | INCONCLUSIVE (probabilmente il blocco rate-limit IAM; vedi Limitazioni) |
Riduci l'esposizione nel frattempo. Limita l'accesso di rete alla suite AD360 (non dovrebbe essere esposta a internet) e, se il percorso di replay non è necessario, disabilitare l'integrazione CustomSSO rimuove completamente la precondizione.