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

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

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)

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

Популярное

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

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

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

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

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

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() впоследствии могла достичь внутреннего пути исключения и возбудить:

root@kitploit:~
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 отклонялся немедленно с:

root@kitploit:~
UnexpectedDER: Length longer than the provided buffer

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

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

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

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


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

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

Новые тесты покрывают отклонение усеченной длины для:

  • remove_octet_string
  • remove_constructed
  • remove_implicit

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

После добавления исправления и тестов полный набор тестов локально прошел:

root@kitploit:~
python -m pytest -q
# 2018 passed, 5 skipped

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

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


Серьезность и классификация

Эта проблема была обоснованно классифицирована как умеренная (Moderate).

Ключевое влияние здесь — доступность/устойчивость, а не конфиденциальность или целостность.

Классификация в уведомлении была следующей:

  • CWE-20: Некорректная валидация входных данных
  • CVSS: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

Это логично.

Утверждение не в том, что некорректный DER позволяет атакующему выполнить код. Утверждение в том, что некорректный DER может вызывать непредвиденные внутренние исключения в программном обеспечении, которое разбирает непроверенный DER-материал с помощью этой библиотеки.

Это реальная и обоснованная ошибка разбора DoS-типа.


Раскрытие

Эта проблема была сообщена приватно через GitHub Security Advisories.

Отчет включал:

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

Мейнтейнер подтвердил проблему, запросил, чтобы исправление вышло вместе с модульными тестами, и скоординированное исправление прошло через временный приватный форк-процесс GHSA.

В ходе обработки CVE GitHub первоначально отказал в назначении, поскольку текст уведомления выглядел так, будто мог описывать более одной уязвимости. Разъяснение было простым:

это была одна уязвимость с одной корневой причиной — некорректная валидация длины DER, — а IndexError в SigningKey.from_der() был нижестоящим следствием того же самого принятия некорректного ввода, а не отдельной независимо исправимой проблемой.

Этого разъяснения оказалось достаточно, и проблеме был присвоен идентификатор:

CVE-2026-33936


Чему на самом деле учит эта ошибка

Урок здесь не в том, что «DER — сложная штука».

Все и так знают, что DER сложен.

Настоящий урок таков:

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

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

Именно так низкоуровневые ошибки разбора становятся проблемами безопасности.

Эта ошибка также подтверждает нечто важное о написании отчетов (writeups) и триаже:

  • корневая причина важна
  • путь влияния важен
  • а аккуратная связка этих двух вещей важна еще больше

«Некорректный ввод принят» — это начало истории.

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

Это различие помогло изложить аргументацию ясно и корректно.


Ключевые моменты

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

Заключение

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

Она была про парсер, который доверял некорректному вводу дольше, чем следовало.

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

Именно поэтому это стало CVE-2026-33936.

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

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