Самый популярный в мире торрент-клиент uTorrent содержал уязвимость, позже получившую название CVE-2020-8437, которая могла быть использована злоумышленниками для создания сбоев в работе программы на устройствах, имеющих доступ к интернету. Будучи белыми хакерами, вместе со своим другом (пожелавшим остаться анонимным), мы сообщили о ней, вскоре, после того, как она была обнаружена, и патч с исправлениями не заставил себя долго ждать. Спустя некоторое время, после того, как большинство пользователей обновили версию своего клиента, настало время раскрыть подробности CVE-2020-8437, вместе со способами ее использования.
Что нужно знать о BitTorrent
При загрузке файлов по протоколу BitTorrent, клиенты используют одновременные подключения к нескольким одноранговым узлам, создавая децентрализованную сеть загрузки. Каждый одноранговый узел может делиться и скачивать данные с любого другого узла, участвующего в обмене, устраняя единственную точку отказа и обеспечивая надежное соединение. Такой подход создает благоприятные условия для более быстрой и стабильной загрузки со всех одноранговых узлов.
Одноранговые узлы, как уже упоминалось ранее, общаются друг с другом с помощью протокола BitTorrent, который инициируется посредством рукопожатия (handshake). Давайте сосредоточимся на нем и пакете, который следует сразу за ним, потому что это все, что нужно для эксплуатации уязвимости CVE-2020-8437 uTorrent. На удивление, все просто.
BitTorrent Handshake
BitTorrent Handshake - это первый пакет, который инициирующий одноранговый узел отправляет другому одноранговому узлу. В нем 5 полей в строго структурированном формате.
BitTorrent Handshake - формат пакета
- Длина названия - 1 байт (unsigned int) - длина следующей строки.
- Название протокола - строка переменной длины - протокол, который использует инициирующий партнер. Это поле предназначено для лучшей совместимости, во всех основных реализациях установлено значение «BitTorrent protocol».
- Зарезервированные байты - 8-байтовое поле - каждый бит которого описывает расширение функциональности протокола, которое не было частью исходной спецификации BitTorrent. Современные торрент-клиенты используют это поле для оптимизированной загрузки файлов. Сегодня подавляющее большинство клиентов поддерживают расширение «Extension Protocol» (сбивающее с толку название, я знаю), 20-й бит используется для обмена информацией о других расширениях. Да, вы правильно поняли: существует расширение, которое позволяет использовать еще больше расширений. Интересно, к чему может привести такой сложный протокол .
- Информационный хэш - 20 байт SHA1 - используется для идентификации торрента, который хочет загрузить инициирующий одноранговый узел. Это хэш, содержащий всю необходимую информацию для загрузки торрента (его имя, описание секций, размер секций, количество секций и т.д).
- Peer ID - 20-байтовый буфер - произвольный идентификатор, который генерирует инициирующий партнер.
После того, как одноранговый узел на другом конце получает вышеназванный пакет от первого клиента, он отвечает своим собственным пакетом в том же формате.
Если оба этих узла устанавливают в поле «Зарезервированные байты» бит «Extension Protocol», то рукопожатие усложняется обменом дополнительной информацией об использумых расширениях, используя иной формат пакета.
BitTorrent Extended Handshake
Расширенный пакет рукопожатия используется одноранговыми узлами с целью обмена информацией о дополнительных расширениях, которые они поддерживают. В отличие от ранее рассмотренного стандартного пакета рукопожатия, размер которого был (практически) статическим, пакет расширенного рукопожатия может динамически увеличиваться, позволяя транспортировать множество дополнительных данных, помимо информации о расширениях.
BitTorrent Extended Handshake - формат пакета
- Длина - 4 байта (unsigned int) - длина всего последующего сообщения
- Тип сообщения BitTorrent - 1 байт - идентификатор сообщения текущего пакета BitTorrent. По умолчанию, установлено значение 20 (0x14).
- Тип сообщения BBitTorrent Extended - 1 байт - Идентификатор расширенного сообщения. По умолчанию, установлен в 0.
- M - динамический размер - зашифрованный словарь, содержащий информацию обо всех дополнительных расширениях.
Бенкодированные словари
Поле M - это бенкодированный словарь, формат которого похож на словарь в Python: каждый ключ соответствует своему значению. Однако, в отличие от словарей в Python, бенкодированные словари описывают длину каждой строки перед ее значением, а «d» и «e» используются вместо «{» и «}» соответственно.
Кроме того, Python словарь может содержать отдельный словарь внутри себя (другой словарь внутри него и т. д.), Бенкодированный словарь тоже так умеет.
Уязвимость CVE-2020-8437
Уязвимость CVE-2020-8437 заключается в том, как uTorrent анализирует бенкодированные словари, в частности, вложенности. До патча (uTorrent 3.5.5 и ранее) uTorrent использовал целое число (32 бита) чтобы отслеживать, какой уровень в бенкодированном словаре он в настоящее время анализирует. Например, когда uTorrent будет анализировать первый уровень, битовое поле будет содержать значение «00000000 00000000 00000000 00000001», а когда uTorrent будет анализировать второй уровень, битовое поле будет содержать значение «00000000 00000000 00000000 00000011».
«Но что произойдет, если uTorrent проанализирует бенкодированный словарь с более чем 32 вложенными в него словарями?», - с любопытством спросили мы с другом однажды вечером в четверг. Быстро создали такой словарь и загрузили его в парсер для кодирования uTorrent. Результат:
Потрясающе! uTorrent крашнулся! Дальнейшее изучение сбоя выявило его источник: разыменование нулевого указателя.
Использование CVE-2020-8437
Существует два простых вектора использования эксплойтов CVE-2020-8437: первый - это удаленный узел, отправляющий пакет расширенного сообщения с вредоносным бенкодированным словарем, а второй - это файл .torrent, содержащий вредоносный бенкодированный словарь.
Удаленный одноранговый эксплойт
Как уже было сказано ранее, когда два одноранговых узла, поддерживающих расширенные сообщения, начинают общаться друг с другом, каждый из них отправляет пакет, в котором перечислены различные поддерживаемые ими расширения. Эта информация о поддерживаемых расширениях отправляется в виде бенкодированного словаря, и поскольку этот словарь анализируется клиентом, если он будет вредоносным (более 32 вложенных уровней словарей), он запускает CVE-2020-8437.
Эксплойт торрент-файла
Файлы .torrent содержат самую основную информацию, необходимую клиенту для начала загрузки торрентов. Эти файлы открыто распространяются на различных сайтах, загружаются, а затем открываются торрент-клиентами, что фактически делает их возможным средством для запуска уязвимостей в этих торрент-клиентах. Позвольте мне взглянуть на внутреннюю структуру торрент-файла за кулисами и показать, насколько просто использовать его для запуска CVE-2020 -8437: торрент-файл - это просто бенкодированный словарь, сохраненный в виде файла. Итак, чтобы использовать CVE-2020-8437 из файла .torrent, вам просто нужно сохранить злонамеренный словарь в бенкодированном виде в файл и дать этому файлу расширение .torrent.
Посмотрите мой эксплойт с торрент-файлом.