Исследование

Драйвер Windows CLFS и пять эксплойтов операторов шифровальщиков (№ 4: CVE-2023-23376)

Это пятая часть нашей статьи о файловой системе CLFS и пяти уязвимостях этого компонента ОС Windows, встречавшихся в кампаниях шифровальщиков на протяжении года. Если вы еще не ознакомились с предыдущими частями, прочтите сначала их.

Вы можете перейти к нужному разделу из содержания или по ссылкам в конце этой части.

Эксплойт № 4: CVE-2023-23376

Октябрьские изменения усложнили эксплуатацию блока GENERAL, и автор описанных выше эксплойтов переключил свое внимание на блок CONTROL. Уязвимость CVE-2023-23376 была обнаружена «в дикой природе» Центром аналитики угроз Microsoft (MSTIC) и Центром реагирования на нарушения безопасности Microsoft (MSRC) как уязвимость нулевого дня. Брешь закрыли в феврале 2023 года.

Для понимания этой уязвимости нужно детально рассмотреть структуру CLFS_CONTROL_RECORD. Как уже упоминалось в первой части нашего исследования, где обсуждалось устройство файловой системы CLFS, эта структура содержит массив структур CLFS_METADATA_BLOCK с информацией обо всех блоках в файле и дополнительные поля, используемые для изменения размера блоков. Нас интересуют поля, связанные с операцией расширения блока: eExtendState — состояние операции (0: нет, 1: расширение, 2: сброс); iExtendBlock — индекс блока, к которому применяется расширение; iFlushBlock — индекс записываемого блока; cNewBlockSectors — размер нового блока (в секторах); cExtendStartSectors — исходный размер блока; cExtendSectors — количество добавленных секторов.

Когда драйвер открывает существующий файл BLF, функция CClfsBaseFilePersisted::OpenImage проверяет, должна ли быть продолжена прерванная операция расширения блока.

Функция CClfsBaseFilePersisted::OpenImage

Функция CClfsBaseFilePersisted::OpenImage

Эта функция проверяет индексы iExtendBlock и iFlushBlock. Их значения должны быть меньше шести. В противном случае указатель блока будет считан за пределами буфера с картой блоков m_rgBlocks в функции ExtendMetadataBlock.

Важно отметить, что функция ExtendMetadataBlock не проверяет индексы iExtendBlock и iFlushBlock. Эти индексы проверяются только функцией OpenImage, которая вызывает ExtendMetadataBlock. Однако функция ExtendMetadataBlock может быть вызвана и другими функциями, которые не проверяют индексы. Предполагается, что «неправильные» индексы могут поступить только из файла на диске, а этот случай охватывают проверки, выполняемые функцией OpenImage. Достаточно ли этого? Не совсем. Если заставить код использовать вредоносную структуру CLFS_CONTROL_RECORD или «неправильные» индексы после первоначальной проверки в OpenImage, в качестве указателя на блок можно передать произвольный адрес и повысить уровень привилегий.

Также стоит отметить, что эксплойты на основе структуры CLFS_CONTROL_RECORD не являются чем-то новаторским. Точно такой метод атаки уже был описан в статье Exodus Intelligence об использовании уязвимостей CVE-2021-36955, CVE-2021-36963 и CVE-2021-38633. Автор эксплойта, скорее всего, прочел эту статью и понял, что функцию ExtendMetadataBlock можно задействовать снова, используя старые методы из эксплойтов для блока GENERAL.

Эксплойт изменяет в только что созданном файле BLF много байтов.

  1. Эксплойт перемещает легитимную структуру CLFS_ CONTROL_RECORD на относительный адрес 0x1FF, чтобы относительный адрес поля DumpCount совпал с относительным адресом сигнатуры сектора.
  2. Значения eExtendState, iExtendBlock, iFlushBlock и других полей в структуре CLFS_CONTROL_RECORD изменяются так, чтобы код выполнял функцию ExtendMetadataBlock из функции OpenImage.
  3. Эксплойт создает вредоносную структуру CLFS_CONTROL_RECORD по относительному адресу 0x2FF.
  4. Эксплойт увеличивает значение cbSymbolZone в записи блока GENERAL таким образом, чтобы функция ExtendMetadataBlock выполнялась повторно при попытке кода добавить новый символ.
  5. Эксплойт модифицирует CLFS_LOG_BLOCK_HEADER->SignaturesOffset точно так же, как эксплойт № 2, но на этот раз для блока CONTROL. Массив с оригинальными байтами из последнего сектора, где он должен находиться, перемещается в первый сектор, где расположен заголовок блока (относительный адрес перед вмешательством: 0x3F8, относительный адрес после вмешательства: 0x28).
Наложение нового массива данных сигнатур на существующий заголовок блока

Наложение нового массива данных сигнатур на существующий заголовок блока

В результате изменений, выполненных в шагах с 1 по 5, относительный адрес записи теперь накладывается на местоположение оригинальных байтов сектора 0, а сигнатура сектора 0 частично накладывается на CLFS_CONTROL_RECORD->DumpCount.

Наложение поля CLFS_CONTROL_RECORD->DumpCount и сигнатуры сектора 0

Наложение поля CLFS_CONTROL_RECORD->DumpCount и сигнатуры сектора 0

Как вы уже догадались, первопричина этой уязвимости практически идентична причине, которая сделала возможным эксплойт № 2. Главное отличие состоит в том, что в этот раз мишенью эксплойта является структура CLFS_CONTROL_RECORD, а не CLFS_BASE_RECORD_HEADER. Поля RecordOffsets[0] и DumpCount теперь соединены сигнатурой сектора 0, и вот к чему это ведет.

  1. При открытии файла BLF функция ClfsDecodeBlock копирует оригинальные байты из CLFS_LOG_BLOCK_HEADER->RecordOffsets[0] в местоположение сигнатуры сектора 0 (оно же — поле CLFS_CONTROL_RECORD->DumpCount). По относительному адресу 0x1FE находится слово 0x1FF.
  2. Код переходит к функции ExtendMetadataBlock, которая вносит изменения в CLFS_CONTROL_RECORD. Значение в поле DumpCount инкрементируется. По относительному адресу 0x1FE теперь находится слово 0x2FF.
  3. Функция FlushMetadata вызывает функции WriteMetadataBlock/ClfsEncodeBlock для кодирования блоков и записи изменений на диск.
  4. ClfsEncodeBlock кодирует обновленные оригинальные байты из позиции сигнатуры сектора 0 в местоположение, где они должны храниться, перезаписывая при этом CLFS_LOG_BLOCK_HEADER->RecordOffsets[0] (0x1FF -> 0x2FF).
  5. Эксплойт добавляет новый контейнер и, поскольку значение cbSymbolZone изменено, функция ExtendMetadataBlock выполняется снова, но теперь вместо легитимной записи используется вредоносная структура CLFS_CONTROL_RECORD.

В результате эксплойт заставляет код использовать указатель, внедренный в память в качестве указателя блока, и принять «неправильные» индексы iExtendBlock и iFlushBlock. Функция WriteMetadataBlock, вызываемая из функции ExtendMetadataBlock, использует указатель блока для увеличения значения в поле DumpCount, что позволяет увеличить произвольное значение в памяти. В операционных системах, которые поддерживают прием PreviousMode, это позволяет повредить другой файл BLF, после чего реализуется тот же процесс, что и во всех предыдущих эксплойтах. В свежих сборках Windows 11, которые не поддерживают прием PreviousMode, эта уязвимость используется для того чтобы повредить поля атрибутов канала (pipe) и создать примитив считывания-записи произвольной памяти с помощью функции API NtFsControlFile.

Перейдите по ссылке, чтобы ознакомиться со следующей частью:

Драйвер Windows CLFS и пять эксплойтов операторов шифровальщиков (№ 4: CVE-2023-23376)

Ваш e-mail не будет опубликован. Обязательные поля помечены *

 

Отчеты

CloudSorcerer: новая APT-угроза, нацеленная на российские государственные организации

«Лаборатория Касперского» обнаружила новую APT-угрозу CloudSorcerer, нацеленную на российские государственные организации и использующую облачные службы в качестве командных серверов аналогично APT CloudWizard.

StripedFly: двуликий и незаметный

Разбираем фреймворк StripedFly для целевых атак, использовавший собственную версию эксплойта EternalBlue и успешно прикрывавшийся майнером.

Подпишитесь на еженедельную рассылку

Самая актуальная аналитика – в вашем почтовом ящике