А вы знали, что вполне легитимный драйвер может дать злоумышленнику возможность прописаться в вашей системе надолго, оставаясь внутри даже после ее переустановки? Или превратить ваш компьютер в кирпич? Например, некоторые безобидные на вид доверенные (подписанные) драйверы являются попутно инструментами для перезаписи BIOS. После такой атаки спасет лишь программатор.
В ОC Windows существуют доверенные приложения/скрипты/библиотеки с дополнительной интересной опасной функциональностью вроде исполнения произвольного кода, загрузки файлов, обхода UAC и т.п. Если подобная дополнительная функциональность встречается у компонента ядра, становится еще интереснее.
Начиная с Windows Vista x64, действует политика Driver Signature Enforcement (DSE) – все драйверы уровня ядра должны быть подписаны. Если злоумышленник (с правами пользователя/администратора) после проникновения в систему жаждет получить максимальный уровень доступа (установить kernel rootkit/bootkit/SMM-rootkit/BIOS-rootkit), ему придется как-то обойти требование подписи для драйвера. Возможность вызова из юзермода некоторых функций или инструкций в режиме ядра может дать злоумышленнику инструмент для повышения привилегий, раскрытия информации или вызова отказа в обслуживании. Назовем такую функциональность функциональностью двойного назначения (в некоторых случаях подобное могут называть уязвимостями или бэкдорами, однако дискуссия на тему корректности определения выходит за рамки этой статьи).
Способы обхода DSE
Давайте рассмотрим, какие вообще варианты есть у злоумышленника для обхода DSE (надо же как-то проникнуть в ring0). В таблице ниже собраны способы обхода DSE с их преимуществами и недостатками (для злоумышленника, а безопасники принимают к сведению). Стоит отметить, что данная информация относится к Windows x64, начиная с Vista.
Способ | Преимущества | Недостатки |
---|---|---|
Настройка Boot Configuration Data (Test Mode) | Простота |
|
Использование скомпрометированного секретного ключа | Возможность установки любого драйвера |
|
Использование уязвимости в реализации контроля DSE | Не обнаруживается антивирусами и системами безопасности Windows |
|
Модификация механизмов проверки драйверов (bootmgr, winload.exe, winresume.exe, ci.dll) | Возможность установки любого драйвера без проверок OC |
|
Использование подписанного драйвера с уязвимостью | Сложность обнаружения атаки |
|
Использование подписанного драйвера с функциональностю двойного назначения | Не обнаруживается антивирусами и системами безопасности Windows |
|
Как видно по таблице, подписанный драйвер с функциональностю двойного назначения является наиболее привлекательным для атакующего способом обхода DSE.
Опасная функциональность или функциональность двойного назначения
Рассмотрим примеры вредоносных возможностей, которые появляются у злоумышленника при наличии драйвера с опасными функциями двойного назначения.
- Повышение привилегий до уровня администратора/SYSTEM. Требуется чтение/запись физической памяти. Данную атаку можно совершить, например, с помощью драйвера ASMMAP от ASUS. Для этого надо прочитать физическую память и найти структуру EPROCESS (она является элементом связного списка), после чего пройтись по списку в поисках процесса, чей уровень привилегий мы хотим повысить, а также некоторого известного процесса с уровнем SYSTEM (например, lsass, wininit). Затем скопировать значение поля Token структуры системного процесса в структуру целевого процесса. Более детальное описание атаки приведено здесь.
- Отключение SMEP. Для этого нужна запись в управляющий регистр cr4 (точнее, сброс его 20-го бита). Например, драйвер bandainamcoonline.sys не только отключает SMEP, но и услужливо исполняет код по переданному в него от пользователя указателю. Для заинтересовавшихся есть статья с подробным описанием работы драйвера.
Исполнение произвольного кода в режиме ядра. Требуется чтение/запись физической памяти и MSR. Смысл заключается в замене адреса (находится в одном из MSR), на который будет осуществлен переход при совершении системного вызова, на адрес расположения кода злоумышленника. Тут можно найти больше информации об этом. Попутно будет мешать PatchGuard, но с ним при желании можно разобраться.
Поскольку драйвер и PatchGuard оба выполняются в Ring 0, ничто не мешает драйверу отключить проверки PatchGuard (до тех пор, конечно, пока Microsoft не прислушается к Intel и не выйдет за рамки модели с двумя кольцами защиты). Разработчики ядра в Microsoft прекрасно осведомлены об этом факте и выполняют различные действия для скрытия расположения этого кода, обфускации его действий и используемых внутренних структур. Иными словами, из-за невозможности помешать вам модифицировать код PatchGuard они пытаются изо всех сил его скрыть.
— Blunden B. The Rootkit arsenal: Escape and evasion in the dark corners of the system.
ОригиналGiven that driver code and PatchGuard code both execute in Ring 0, there's nothing to prevent a KMD from disabling PatchGuard checks (unless, of course, Microsoft takes a cue from Intel and moves beyond a two-ring privilege model). The kernel engineers at Microsoft are acutely aware of this fact and perform all sorts of programming acrobatics to obfuscate where the code resides, what it does, and the internal data-structures that it manipulates. In other words, they can't keep you from modifying PatchGuard code, so they're going to try like hell to hide it.
— Blunden B. The Rootkit arsenal: Escape and evasion in the dark corners of the system.
- Запись BIOS. Пример in the wild – Lojax. Злоумышленники взяли всем известный RwDrv.sys и использовали его для своих грязных целей: прочитали BIOS, модифицировали и записали обратно. Переустановка Windows тут не поможет, так как вредоносный код сидит в прошивке на SPI-flash. Если же перезаписать BIOS неудачно (или специально затереть), то тоже будет неприятно. В любом случае придется сгонять за программатором для исправления досадных последствий.
- Вызов SMI-обработчика. Во-первых, не все BIOS’ы одинаково беззащитны против кода в режиме ring0: есть различные механизмы защиты от чтения/записи, так что возможна ситуация, при которой понадобится лезть ниже – в режим SMM (самый привилегированный). Один из способов туда попасть из режима ядра – дернуть SMI-обработчик (довольно часто среди них встречаются уязвимые). Для вызова SMI-обработчика надо иметь возможность писать в I/O порт, а это можно сделать только с привилегиями ring0. То есть драйвер с возможностью записи в I/O порты способен обнаружить уязвимый SMI-обработчик, который может дать злоумышленнику исполнять код в режиме SMM. В примере автор использует драйвер RwDrv.sys.
- Информация о системе. Чтение памяти ядра (через чтение физической памяти), чтение BIOS, информация о настройках системы, подключенных устройствах и включенных/отключенных механизмах защиты (через чтение MSR, управляющих регистров, доступ к портам ввода/вывода), в некоторых случаях можно детектировать известный гипервизор (типа VirtualBox через MSR). Для данной задачи чаще всего подойдет даже драйвер, который может только читать, не обязательно писать. Например, для чтения физической памяти подойдет RamCaptureDriver64.sys от Belkasoft.
Если проанализировать различные статьи и заметки о CVE, то можно выделить некоторую классификацию потенциально опасных при доступе из ring3 функций в драйверах. В таблице ниже указаны опасные функции и источники информации о них.
Выявленные опасные функции | Источники информации о способах нарушения безопасности |
---|---|
Чтение/запись регистров MSR | CVE-2018-10711, CVE-2018-18535, CVE-2018-19323, CVE-2007-5633, CVE-2007-5761 |
Чтение/запись портов ввода/вывода | CVE-2018-10712, CVE-2018-18536, CVE-2018-19322 |
Чтение/запись физической памяти | CVE-2018-16712, CVE-2018-10710, CVE-2017-15302, CVE-2017-15303, CVE-2018-19321 |
Чтение/запись управляющих регистров | CVE-2018-10709, Eset — Windows exploitation in 2016 |
Доступ к счетчикам мониторинга производительности/тактов | Leif Uhsadel, Andy Georges, Ingrid Verbauwhed — Exploiting Hardware Performance Counters |
Чтение/запись регистра флагов | Wojtczuk R., Rutkowska J. Following the White Rabbit: Software attacks against Intel VT-d technolog |
Инструкции обращения к кэшу | Cache-Based Side-Channel Attacks Detection through Intel Cache Monitoring Technology and Hardware Performance Counters |
И это далеко не весь список возможных опасных функций. Можно также говорить и о чтении/записи виртуальной памяти ядра, чтении/записи MMIO, доступе к PCI устройствами т.д.
Наибольший интерес, а также наибольшую опасность (и наибольшую вероятность обнаружить драйвер с такими функциями) представляют первые три функции: чтение/запись регистров MSR, чтение/запись портов ввода/вывода, чтение/запись физической памяти. С помощью управляющих регистров можно обойти некоторые механизмы защиты, запись в регистр флагов позволяет включить чтение/запись портов ввода/вывода в ring3 (кстати, упоминается в этой статье на Хабре), успех атак по сторонним каналам (с помощью обращения к кэшу, счетчиков мониторинга производительности/тактов), скорее всего, маловероятен.
В процессе создания данного материала на конференции DEFCON 27 в Лас-Вегасе исследователи Jesse Michael и Mickey Shkatov представили работу "Get off the kernel if you cant drive", в которой также рассказывается о данной проблеме, и мы рекомендуем изучить данный материал для полноты картины. Здесь очень просто и наглядно расписаны сценарии использования подобных драйверов и представлены примеры участков кода, отвечающих за наиболее критичную функциональность. И также представлен код по работе и поиску подобных драйверов.
Вообще стоит отметить, что данная тема уже достаточно давно волнует исследователей безопасности. Еще в 2018 году исследователь Александр Матросов в своей статье "What makes OS drivers dangerous for BIOS?" поднимал данный вопрос и демонстрировал, как достаточно просто можно проэксплотировать BIOS.
Драйверы с функциями двойного назначения
Ниже рассмотрены наиболее известные представители драйверов с функциями двойного назначения.
RwDrv.sys – очень популярный драйвер (поставляется с утилитой RWeverything). Читает и пишет физическую память, I/O порты, MSR и управляющие регистры. Был неоднократно использован в разных PoC’ах, а потом и в настоящем ранее упомянутом рутките Lojax. Для него написан интерфейс на C++, а также он используется в chipsec.
cpuz/gpuz
Читает и пишет физическую память, порты и MSR. Есть несколько PoC-утилит с его использованием (здесь и здесь).
pcdsrvc_x64 – драйвер от Dell, за дополнительной информацией обращаться в этот пост. Позволяет читать/писать физическую память и в I/O порты.
AsIO64.sys
Он предоставляет возможность чтения/записи физической памяти и I/O портов, а также вместе с ним идет удобная dll’ка для выполнения этих запросов.
Asmmap64.sys – еще один драйвер от ASUS, позволяющий читать/писать физическую память, I/O порты и MSR. Для злоумышленника он был бы особенно приятен, поскольку доступ к драйверу может быть осуществлен от обычного пользователя без прав администратора. Любопытные могут обратиться к первоисточнику.
ntiolib_x64.sys/winio64.sys – драйверы от MSI, подробно о них рассказано в ранее упомянутой статье. С помощью ntiolib_x64.sys можно читать/писать физическую память, I/O порты и MSR, winio64.sys предоставляет все эти функции, кроме MSR.
Обычно описанные опасные функции признают уязвимостями, если драйвер доступен пользователю без прав администратора (неправильный ACL) или когда позволяет исполнять произвольный код напрямую (как в bandainamcoonline.sys). В остальных случаях это просто функциональность, и раз у пользователя есть права администратора, то он может использовать все функции драйверов и это норма.
Если вы думаете, что подобных драйверов не больше десятка, то сильно ошибаетесь. Можете посмотреть данную подборку интересных драйверов. В этом списке есть драйверы от ASUS, AVAST, Razer, LG, American Megatrends и других известных компаний. Так что их много, нужно просто поискать. А значит, они представляют реальную угрозу.
Данную угрозу понимают и сотрудники Microsoft. И будут признательны за информацию о подобных драйверах ;)
Рекомендации
Для пользователей:
- Не стоит сидеть без необходимости под админской учетной записью, отключать UAC (хотя его обойти не сложно).
- Можно установить детектор пытающихся установиться драйверов (например, вот).
- При необходимости использования утилит с такими драйверами (диагностических, для обновления BIOS и т.п.) удалять драйверы после использования.
- Настроить Device Guard (если вы являетесь счастливым обладателем Windows 10). С помощью этой технологии можно создать свою политику целостности кода, внести "белые" списки программ и сертификатов. Например, добавить в политику требование, что любой драйвер режима ядра должен иметь подпись WHQL от Microsoft. В этом посте можно лучше ознакомиться с настройкой Device Guard для данной цели.
Производителям же лучше не подписывать такие драйверы. Если пользователю требуется обновить BIOS, проверить систему на наличие уязвимостей (привет, chipsec), измерить производительность или провести еще какие-нибудь манипуляции, требующие установки подобных драйверов, то он вполне может перейти в Test Mode, сделать все это, а после выйти. Usability в таком случае упадет, зато возрастет security.
Выводы
Если что-то подписано, то доверять этому все равно нельзя. Во-первых, подписать так-то можно что угодно, а во-вторых, этим подписанным (даже если оно от доверенного производителя) может воспользоваться злоумышленник.
Специалистам по информационной безопасности не стоит исключать из модели угроз ситуации, когда злоумышленнику для выполнения атаки требуется драйвер с опасным функционалом. Драйверов таких достаточно, сделать это довольно просто. Если же атака будет проведена не с таким попсовым драйвером, как от RwEverything, а с каким-нибудь менее широко известным, то обнаружить ее будет еще сложнее. Так что надо быть начеку, мониторить такие вещи и не позволять каждому драйверу загружаться в систему.
Автор: Елизавета Хоменко