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

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

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

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

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

Категории

Все категории
Loading categories
CVE-2026-33936 — Уязвимость типа «Отказ в обслуживании» в ecdsa (PyPI) | Kitploit
Инструменты/GitHubGitHub/0xmrma/cve-2026-33936
Анализ уязвимостейАнализ КодаКриптографияСтатьи и ИсследованияОбучение и Образование
GitHub0xmrma/cve-2026-33936

CVE-2026-33936

Уязвимость типа «Отказ в обслуживании» в ecdsa (PyPI)

Репозиторий
1226 месяцев назадЕщё не проверено

Популярное

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

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

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

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

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

CVE-2026-33936

Уязвимость типа «Отказ в обслуживании» в ecdsa (PyPI)

Введение

Я выявил и ответственно раскрыл уязвимость умеренной степени серьезности (Moderate) в python-ecdsa — широко используемой криптографической библиотеке Python с 47,8 млн загрузок за последний месяц.

Я нашел эту проблему при анализе python-ecdsa, задавшись очень конкретным вопросом:

Что произойдет, если некорректный DER лжет о своей длине, а парсер доверяет ему слишком долго?

В данном случае этот вопрос привел к реальной ошибке.

Вспомогательные функции разбора DER в ecdsa.der принимали усеченные данные в тех случаях, когда закодированная длина заявляла больше байт, чем фактически присутствовало. Такой некорректный ввод должен был отклоняться немедленно. Вместо этого он мог пройти глубже в логику разбора и в конечном счете вызвать внутреннее исключение IndexError при разборе ключа.

Эта проблема стала CVE-2026-33936.

Проект: python-ecdsa на GitHub
Пакет: ecdsa (pip)
CVE: CVE-2026-33936

photo0

Цепочка атаки

attacker-controlled malformed DER → truncated length accepted as valid → parser continues past trust boundary → SigningKey.from_der() reaches internal exception path → unexpected IndexError / application-level DoS risk


Что делает python-ecdsa

python-ecdsa — широко используемая библиотека Python для криптографии на эллиптических кривых.

Помимо прочего, она обеспечивает:

  • разбор ключей
  • сериализацию ключей
  • декодирование DER/ASN.1
  • процессы подписания и проверки подписей

Это означает, что ее код разбора находится непосредственно на границе безопасности.

Когда библиотека принимает внешние ключевые материалы или структурированные бинарные данные, корректность — это не просто вопрос качества. Это свойство безопасности.

Если некорректный ввод принимается тогда, когда он должен быть отклонен, нижестоящий код начинает строить предположения на основе невалидного состояния. Именно здесь ошибки перестают быть «просто ошибками разбора» и начинают становиться уязвимостями.


Почему эта поверхность заслуживала внимания

Разбор DER — одна из тех областей, где небольшие ошибки валидации могут иметь непропорционально серьезные последствия.

Класс ошибки прост:

  • поле длины говорит одно
  • фактический буфер содержит меньше
  • парсер доверяет заявленному слишком долго
  • последующий код работает с состоянием, которого никогда не должно было существовать

Это именно тот вид нарушения границы, который стоит проверять при аудите безопасности.

Я не искал здесь странного криптографического поведения. Я искал ошибки доверия в обработке структурированного ввода.

Это было правильное место для поиска.


Корневая причина

Корневая проблема заключалась в некорректной валидации полей длины DER при разборе некорректно сформированного или усеченного ввода.

В частности, ecdsa.der.remove_octet_string() принимала ввод, в котором объявленная длина DER превышала фактическое количество доступных в буфере байт.

То есть вместо отклонения некорректного DER, например:

  • объявленная длина: 4096
  • фактическое количество оставшихся байт: 3

вспомогательная функция принимала его и возвращала усеченное содержимое как валидное.

Это уже ошибка.

Но более сильное влияние проявилось ниже по цепочке.

Поскольку некорректный ввод был принят, а не отклонен на границе, SigningKey.from_der() впоследствии могла достичь внутреннего пути исключения и возбудить:

IndexError: index out of bounds on dimension 1

Это важно, потому что это не тот вид отказа, который вызывающий код ожидает от некорректного ввода. Правильное поведение — чистое отклонение при разборе, например UnexpectedDER или ValueError.

Таким образом, уязвимость заключалась не в самом по себе «существовании IndexError».

Реальная уязвимость заключалась в следующем:

  • поля длины некорректного DER не валидировались должным образом
  • усеченный ввод пересек границу разбора
  • нижестоящий код в результате попал на внутренний путь исключения

Это одна цепочка ошибок, а не две не связанные между собой проблемы.


Почему это проблема безопасности, а не просто небрежность при разборе

Отклонение некорректного ввода парсером — не косметическое улучшение. Это часть модели безопасности.

Здесь важное различие не в том, был ли ввод невалидным. Разумеется, он был невалидным.

Важное различие в том, как библиотека повела себя перед лицом невалидного ввода.

Существует реальная разница между:

  • чистым отклонением некорректного DER на границе и
  • принятием некорректного DER, продолжением разбора и падением с внутренним исключением

Первое — это надежное поведение.

Второе создает риск на уровне приложения, если программное обеспечение разбирает непроверенный DER и предполагает, что сбои библиотеки остаются в пределах ожидаемых типов исключений.

Именно поэтому данная проблема была корректно классифицирована как уязвимость, а не просто как ошибка качества парсера.


Доказательство концепции (PoC)

Я использовал два PoC, поскольку они демонстрировали две разные части одной и той же цепочки ошибок.

PoC 1: принятие усеченного DER

Первый PoC показал, что remove_octet_string() принимала усеченный DER, объявленная длина которого превышала доступный буфер.

Это установило основной сбой валидации:

  • буфер был короче закодированной длины
  • вспомогательная функция должна была отклонить его
  • она этого не сделала

PoC 2: детерминированный путь внутреннего исключения

Второй PoC показал более важный нижестоящий эффект: некорректно сформированный DER, переданный в SigningKey.from_der(), детерминированно вызывал внутреннее IndexError до исправления.

Это установило значимое для безопасности влияние:

  • некорректный ввод пересек границу
  • разбор продолжился слишком далеко
  • код библиотеки возбудил внутреннее исключение вместо чистой ошибки разбора

Это гораздо более сильный результат, чем «парсер принял странные байты». Он показывает нарушение границы плюс реальные операционные последствия.


Почему PoC были выбраны именно так

Первый PoC доказывает корневую причину.

Второй PoC доказывает влияние.

Такое разделение важно.

Многие отчеты останавливаются на:

«этот парсер принимает некорректные данные».

Это полезно, но не всегда достаточно, чтобы показать, почему ошибка важна.

В данном случае более сильный отчет был таким:

  • некорректный DER ошибочно принимается
  • это принятие не изолировано
  • оно может распространиться на аварийный путь внутреннего исключения при разборе ключа

Это делает историю безопасности гораздо более ясной.


Анализ исправления

Исправление было минимальным и корректным.

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

объявленная длина должна помещаться в доступный буфер

Эта проверка была применена к:

  • remove_constructed()
  • remove_implicit()
  • remove_octet_string()

После добавления этих проверок границ некорректно сформированный/усеченный DER отклонялся немедленно с:

UnexpectedDER: Length longer than the provided buffer

А PoC, который ранее вызывал IndexError, больше не достигал внутреннего пути исключения. Он завершался сбоем чисто во время разбора — именно так и должно было быть с самого начала.

Это тот тип исправления, который вы хотите видеть в уязвимости парсера:

  • узкое
  • явное
  • напрямую связанное с границей доверия
  • легко поддающееся анализу
  • подкрепленное регрессионными тестами

Никакого редизайна. Никакой двусмысленности. Просто корректная валидация там, где она отсутствовала.


Регрессионные тесты

Я также добавил целенаправленные регрессионные тесты, чтобы гарантировать, что именно этот класс некорректного DER остается отклоненным.

Скачать инструмент