
Script de detecção para CVE-2026-11374
Um script de detecção para a pré-condição de exploração do CVE-2026-11374, uma falha previsível de ticket SSO que leva à tomada de conta não autenticada em toda a suíte ManageEngine AD360. Os quatro produtos no escopo compartilham o ManageEngineADSFramework:
| Produto | Build afetada | Build corrigida |
|---|---|---|
| ADSelfService Plus | ≤ 6528 | 6529 |
| RecoveryManager Plus | ≤ 6320 | 6321 |
| M365 Manager Plus | ≤ 4816 | 4817 |
| ADAudit Plus | ≤ 8702 | 8703 |
Nas builds afetadas, o ticket SSO é apenas System.currentTimeMillis() (um timestamp previsível) amostrado no login da vítima, portanto pode ser repetido por meio do cookie CUSTOM_SSO_TICKET para sequestrar essa sessão. A correção substitui o ticket por UUID.randomUUID() (um identificador suficientemente aleatório). O caminho de repetição só é alcançável quando o produto é integrado ao AD360: o ADSFilter o condiciona a isProductIntegrated(). Essa condição é a pré-condição que esta ferramenta verifica.
NOTA: este detector confirma a pré-condição, não a vulnerabilidade em si. Um resultado
POTENTIALLY_AFFECTEDnão é um veredito de vulnerabilidade confirmada — veja abaixo para mais informações.
Sim. Foi desenvolvido para uso em produção e avaliação.
1700000000000, um valor em milissegundos antigo o suficiente para nunca estar residente em cache), portanto nenhuma sessão é recuperada. O servidor apenas nos diz para limpar os cookies que enviamos.GET simples, e os únicos cookies afetados são os descartáveis que a ferramenta envia.O patch do CVE-2026-11374 alterou apenas a forma como o ticket é gerado (de milissegundos para UUID); não alterou o caminho de repetição de cookie que esta sonda exercita. Como resultado, uma instalação corrigida responde byte a byte de forma idêntica a uma vulnerável para qualquer requisição não autenticada.
O que a ferramenta pode fazer, de forma não autenticada e não destrutiva:
O que não pode fazer:
POTENTIALLY_AFFECTED significa que a pré-condição é atendida e que você deve verificar o nível do patch, não que o host esteja confirmado como vulnerável.conf/product.conf localmente ou resolver ativamente um ticket ativo (exploração real, intencionalmente não implementada aqui).?build= do ADSSP às vezes é a build real e às vezes um placeholder congelado que exibe um valor abaixo da build corrigida, portanto um valor abaixo do corrigido é ambíguo e a ferramenta o marca como inconclusivo. Um valor igual ou acima da build corrigida continua sendo um sinal confiável de correção, pois o placeholder é sempre baixo demais para alcançá-lo.requests. Instale com 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
As portas padrão diferem por produto (ADSelfService Plus 8888, ADAudit Plus 8081, M365 Manager Plus 8365, RecoveryManager Plus 8090), portanto informe uma URL ou host:port. Um host sem porta usa 8888 por padrão.
Um console integrado ao AD360 (detalhado, o padrão). A segunda linha esclarece que isto é a pré-condição e não um veredito de vulnerabilidade; a terceira é a dica de build de melhor esforço:
$ ./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)
Uma instalação independente do mesmo produto, onde o caminho de repetição não está ativo:
$ ./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.
Escaneando uma lista com uma linha alinhada por host (--brief). O status de saída é 1 se algum host for POTENTIALLY_AFFECTED, caso contrário 0, o que é prático em scripts. A nota final mostra o produto identificado, além do número de build em um resultado:
$ ./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
Saída legível por máquina (--json). Cada resultado carrega o verdict, o state e o detail por trás dele, o product identificado e — quando há um resultado — um objeto build: build é o número encontrado, fixed_build é o limite para aquele produto, patch_hint é a indicação direcional (likely_patched para igual ou acima da build corrigida, caso contrário inconclusive), e note é uma breve explicação:
$ ./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"
}
]
| Código | Significado |
|---|---|
0 | Nenhum alvo retornou POTENTIALLY_AFFECTED |
1 | Pelo menos um alvo é POTENTIALLY_AFFECTED |
2 | Erro de uso (argumentos inválidos / arquivo de alvos ilegível) |
Envie um ticket inválido mais uma tag de aplicativo para qualquer URL CustomSSO (*.do):
GET /AppsHome.do
Cookie: CUSTOM_SSO_TICKET=1700000000000; CUSTOM_SSO_APP_TAG_NAME=AD360
Em uma instalação integrada ao AD360, a cadeia ADSFilter → CustomSSOFilter → CookieSSOImpl executa seu ramo de resolução (a tag nomeia um produto diferente, portanto appName != prodName), falha ao resolver o ticket falso e emite cabeçalhos de resposta de limpeza de 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; ...
Uma instalação independente nunca executa esse caminho e não emite limpeza. O produto é identificado por seu cookie de sessão Tomcat fixo por produto (JSESSIONIDADSSP para ADSelfService Plus, e assim por diante), que é definido em cada resposta. A verificação se baseia nos cabeçalhos em vez do código de status, pois um ADSSP integrado retorna 302 enquanto ADAudit, M365 e RMP retornam 200 para a mesma sonda.
POTENTIALLY_AFFECTED não é "vulnerabilidade confirmada". É a pré-condição de exploração. Como o patch não tocou neste caminho de código, uma build corrigida responde de forma idêntica, portanto você precisa confirmar o nível do patch fora de banda (veja os próximos passos). Esse é o teto do que um observador não autenticado pode saber.HTTP 400 pode ser um bloqueio de limite de taxa em vez de uma resposta real. O Zoho IAM aplica um throttle contínuo por URL que limita um IP de origem a cerca de 40 requisições por 60 s e então bloqueia aquele caminho por ~60 s. Durante o bloqueio, as requisições retornam HTTP 400 e o sinal de integração é mascarado. A ferramenta reporta esses casos como INCONCLUSIVE; tente novamente a partir desse IP após cerca de um minuto.UNAFFECTED. Confirme diretamente se você espera um produto ManageEngine lá.?v=) e M365 (?bN=) sempre expõem a build real; o ?build= do ADSSP às vezes é real e às vezes um placeholder congelado que exibe um valor abaixo da build corrigida, portanto um valor de ADSSP abaixo do corrigido é ambíguo; o RMP não expõe nenhum. Em todos os casos, uma build igual ou acima da build corrigida indica fortemente que está corrigido, e abaixo dela é inconclusivo.Se um alvo retornar POTENTIALLY_AFFECTED, trate-o como exposto e digno de confirmação. Em seguida:
Confirme o nível do patch diretamente (a ferramenta não consegue). Leia conf/product.conf (build_number) no host e compare com a build corrigida daquele produto (ADSelfService Plus 6529, RecoveryManager Plus 6321, M365 Manager Plus 4817, ADAudit Plus 8703). Interprete de forma direcional: uma build igual ou acima da build corrigida é um forte indicador de que o host está corrigido, pois a correção do UUID está nessa árvore. Uma build abaixo da build corrigida é inconclusiva em vez de prova de vulnerabilidade, porque hotfixes e backports fora de banda podem aplicar a correção do UUID sem aumentar o número da build; nesse caso, recorra à verificação do formato do ticket abaixo.
Verifique o formato do ticket emitido se puder fazer login. O cookie CUSTOM_SSO_TICKET não é HttpOnly, portanto após autenticar você pode ler seu valor: um número de 13 dígitos significa vulnerável, um UUID significa corrigido. Esta é a verificação positiva mais clara.
Atualize para a build corrigida (ou posterior) em qualquer host que esteja vulnerável ou que você não consiga confirmar como corrigido. A correção substitui o ticket previsível por um UUID aleatório.
Procure por tentativas de exploração. No host, serverOut_<date>.txt registra o throttle como rajadas de:
IAMSecurityException ErrorCode: URL_ROLLING_THROTTLES_LIMIT_EXCEEDED,
RequestURI: "/showLogin.cc", RemoteAddr: <source IP>
Um pico de URL_ROLLING_THROTTLES_LIMIT_EXCEEDED nos caminhos de despacho de SSO/login a partir de um único IP de origem é um forte indicador de força bruta de tickets. Revise também os logins bem-sucedidos recentes e a atividade de sessão em busca de sinais de tomada de conta.
Atualize o produto afetado para pelo menos a build corrigida (ADSelfService Plus 6529, RecoveryManager Plus 6321, M365 Manager Plus 4817, ADAudit Plus 8703) ou posterior. A correção substitui o ticket SSO previsível System.currentTimeMillis() por UUID.randomUUID().
Este código é distribuído sob uma licença MIT.
O uso desta ferramenta para atacar alvos sem consentimento mútuo prévio é ilegal. É responsabilidade do usuário final obedecer a todas as leis locais, estaduais e federais aplicáveis. Os desenvolvedores não assumem nenhuma responsabilidade e não são responsáveis por qualquer uso indevido ou dano causado por este programa.
| Flag | Descrição |
|---|
targets | Um ou mais host, host:port ou https://host:port |
-f, --targets-file FILE | Lê os alvos de um arquivo (um por linha; comentários #) |
--brief | Uma única linha alinhada por alvo, boa para escanear muitos hosts |
--json | Emite resultados JSON estruturados |
--timeout SECS | Tempo limite por requisição (padrão: 15) |
--no-build | Pula a requisição extra do número de build em um resultado positivo |
--no-color | Desativa a saída colorida (também respeita NO_COLOR e não-TTY) |
| Veredito | Significado |
|---|
POTENTIALLY_AFFECTED | Produto no escopo integrado ao AD360; o caminho de repetição de cookie CustomSSO está ativo, portanto a pré-condição de exploração do CVE-2026-11374 é atendida. Este não é um veredito de vulnerabilidade confirmada; verifique o nível do patch (veja os próximos passos). |
UNAFFECTED | O caminho de repetição não é alcançável. Qualquer um destes: um produto no escopo independente (não integrado ao AD360 — embora se torne alcançável se for integrado depois, então verifique a build mesmo assim); um produto do framework ADS da ManageEngine que não seja um dos quatro no escopo; ou nenhum produto no escopo na resposta (não é um dos quatro produtos do CVE-2026-11374, ou um proxy que remove o cookie de sessão). |
INCONCLUSIVE | Um HTTP 400 — provavelmente o bloqueio de limite de taxa do IAM mascarando o sinal; tente novamente após ~60 s. |
ERROR | Falha de conexão/timeout/TLS. |
| Resposta da sonda | Veredito |
|---|
| cabeçalhos de limpeza e um cookie de produto no escopo conhecido | POTENTIALLY_AFFECTED |
| cookie de produto, sem limpeza, status ≠ 400 | UNAFFECTED (independente / não integrado) |
| nenhum cookie de produto no escopo, status ≠ 400 | UNAFFECTED (não é um dos quatro produtos) |
| cabeçalhos de limpeza, mas cookie de produto não reconhecido | UNAFFECTED (ManageEngine, fora do escopo) |
HTTP 400 | INCONCLUSIVE (provavelmente o bloqueio de limite de taxa do IAM; veja Limitações) |
Reduza a exposição enquanto isso. Restrinja o acesso de rede à suíte AD360 (ela não deveria estar exposta à internet) e, se o caminho de repetição não for necessário, desativar a integração CustomSSO remove a pré-condição por completo.