![]() |
Драйверы открывают доступ в ядро ОС, вот только начиная с Win7-x64 Microsoft ввела принудительную их подпись по EV-сертификатам (Extended Validation). А всё потому, что с выходом платформы KMDF (Kernel Mode Driver Frameworks) программирование драйверов стало напоминать игру «Тетрис», в результате чего огромная армия пионеров дружненько заполнила рынок кривыми дровишками. Теперь-же, Windows примет на свой борт только те драйвера, которые прошли жёсткий фейс-контроль в штабе Microsoft, и имеют удостоверяющую личность цифровую печать.
Таким образом, хоть мы и напишем драйвер для своего устройства (интерес представляют исключительно шпионы), загрузить его в систему будет проблематично, а отдавать за подпись шекели как-то не вдохновляет, хотя цены вполне приемлемые от 300 до 700 бакинских коммисаров в год. Поэтому исследователи всех мастей не пишут сейчас свои драйвера, а ищут уязвимости и дыры в уже подписанных модулях. Человеку свойственно ошибаться, а потому сколько приоткрытых люков имеется на данный момент в драйверах, остаётся только гадать. На программном уровне, драйвер олицетворяет структура DRIVER_OBJECT, и она всегда привязывается к какому либо устройству DEVICE_OBJECT. Это устройство может быть как физическим (например порт или диск), так и логическим типа файловой системы FAT/NTFS. Один драйвер способен обслуживать запросы сразу от нескольких устройств одного типа, тогда будем иметь одну структуру DRIVER_OBJECT, и несколько связанных с ней DEVICE_OBJECT. Вот представленная отладчиком WinDbg топология драйвера шины PCI.SYS где видно, что в его команде аж 20 подчинённых устройств, и нужно сказать это не предел (у acpi.sys их 43): Код: Код:
0: kd> !drvobj pciВот пример стека для одного из устройств драйвера PCI.SYS. Коммуникация двух и нескольких устройств в стеке позволяет находить комфортные условия для работы – каждый решает свою задачу, которая превращается в одну глобальную. Код: Код:
0: kd> !devstack fffffa80043c6a10Не возможно атаковать драйвера не зная принципы их функционирования. Чтобы построить абъюзивную схему отношений, здесь нужен вектор нападения. Драйверы основных устройств (таких шины, мосты и прочее) пишутся в закрытых офисах Microsoft, и следовательно они тщательно отшлифованы – найти в них дыры практически нереально. Другое дело фильтр-драйверы, которые инкапсулируются в стек-драйверов устройства (выше или ниже основного драйвера), расширяя тем-самым его базовый функционал. На этом фоне выделяются фильтры файловой системы NTFS. Перед тем-как записать данные на диск, этот фильтр может например зашифровать поток, а при чтении обратно расшифровать. Так работает модуль «BitLocker» в Windows. Когда мы запрашиваем доступ к файлу вызовом Код:
NtCreateFile()Код: Код:
Dispatch routines:1. Не трогая, передать пакет следущему драйверу в стеке. 2. Изменить пакет IRP, и отдать его сл.драйверу. 3. Завершить указанную в IRP операцию с успешным результатом. 4. Завершить операцию IRP с ошибкой. 5. Передав без изменения запрос сл.драйверу, изменить ответ на обратном пути. 6. Передать пакет IRP в стек другого устройства. Это основы работы драйвера фильтра. Важно отметить, что пакет запроса не распространяется сам по всему стеку – цепочка драйверов должна его явно передавать друг-другу, а потому любой из драйверов может остановить продвижение пакета дальше, сразу вернув ответ диспетчеру ввода-вывода. Фильтр файловой системы обычно располагается в стеке сверху драйвера NTFS.SYS, однако это не табу и его можно вставить ниже, что позволит фильтровать не только запросы к FS, но и изменять ответы, модифицируя данные секторов диска. 2. Менеджер фильтров и мини-фильтры Реализовать драйвер фильтра с нуля довольно сложно – нужно будет обрабатывать каждый из 28-ми типов запросов на ввод-вывод IRP_MJ_xx, даже если они нам не нужны. Другая проблема – это позиция фильтра в стеке. Легко прикрепить его первым к вершине, но попытка загнать в середину может привести к катастрофе, т.к. порядок следования фильтров может отличаться от порядка загрузки их в память. Ядро это не юзер-спейс – оно не понимает таких шуток, и сразу падает в бсод. Чтобы упростить написание фильтров, Win поставляется с их диспетчером FLTMGR.SYS, который отвечает за обработку запросов на ввод-вывод, и передачу пакетов IRP по стеку. Так появились драйверы «Мини-фильтра», вместо уже устаревших драйверов фильтра. На следующей схеме показано, как меняется архитектура ввода-вывода, когда в штате появился новый сотрудник в лице «диспетчера фильтров» (выделен синим). Здесь видно, что мини-фильтры не добавляют в стек свои собственные объекты устройств – вместо этого они регистрируются у диспетчера/менеджера, который вызывает мини-фильтры для обработки IRP. Если запрос не поддерживается ни одним из мини-фильтров, диспетчер сам передаёт пакет IRP сл.драйверу в стеке, сводя на нет всевозможного рода ошибки. Лог отладчика подтверждает, что менеджер в стеке располагается выше драйвера NTFS.SYS: Код: Код:
0: kd> !drvobj ntfsКод: Код:
420.000 – 430.000: FilterМини-фильтр сначала должен зарегистрировать своё присутствие функцией Код:
FltRegisterFilter()Код:
FltStartFiltering()Код:
FltUnregisterFilter()https://forum.antichat.xyz/attachmen...853f8b5f1a.png На своём узле я обнаружил всего 2 мини-фильтра, и оба они хукают обращения к низлежащему драйверу NTFS. Первый LuaFV.sys это фильтр модуля UAC, который закрывает смертным юзерам доступ к системным файлам – в дословном переводе означает «Low User Account File Virtualization». Второй FileInfo.sys представляет драйвер, который отвечает за проверку файлов Win на целостность (см.утилиты sfc и dism.exe). Поскольку UAC имеет смысл только в контексте системного диска, фильтр luafv.sys контролирует обращения исключительно к разделу C:\, о чём свидетельствует число экземпляров(1). Просмотреть лист активных томов накопителя можно ключём «Volumes», и по желанию вручную прикреплять/отсоединять мини-фильтры к этим томам ключами «Attach/Detach» соответственно (см.хелп): https://forum.antichat.xyz/attachmen...db2caca65b.png Узнать, к каким именно разделам диска приатачен тот или иной фильтр можно ключём «Instances» – как видим теория выше верна, и под надзором luafv.sys находится раздел(C:\) с установленной системой. Его собрат FileInfo.sys не знает точно, где могут лежать системные файлы для проверки, а потому ведёт перекрёстный огонь сразу по всем томам, в т.ч. и сетевым дискам «Mup». Итого шесть лог.разделов на моих хардах (включая неактивную флешку G:\ под ником Vol#3), которые контролируют шесть указанных на первом скрине экземпляров фильтра: https://forum.antichat.xyz/attachmen...502aa6a7b5.png 4. Природа уязвимостей в мини-фильтрах Чтобы найти баг, злоумышленник должен послать драйверу данные, на которые дров не рассчитывал. Что делает мини-фильтры привлекательными, так это множество каналов связи с ними. Например драйверу мини-фильтра не нужно создавать подчинённый DEVICE_OBJECT для своей жизнедеятельности – этим занимается диспетчер FltMgr.sys. Однако фильтр может создать девайс для своих собственных нужд. Типичный вектор атаки – это когда мы открываем дескриптор «объекта устройства», и отправляем ему управляющие коды FSCTL для анализа уязвимого поведения. Ясно, что это не единственно возможный вариант, а потому рассмотрим поверхностно остальные. 4.1. Порты коммуникации Один из уникальных механизмов связи диспетчера с фильтром – это порт, который мини-фильтр создаёт функцией диспетчера Код:
FltCreateCommunicationPort()Код:
\\FileSystem\FiltersПосле того-как порт связи с мини-фильтром создан, мы можем открыть его по имени, или вызовом из библиотеки FltLib.dll функции Код:
FilterConnectCommunicationPort()Код:
!fltkd.helpДиспетчер предоставляет сл.функции из своей тушки FltMgr.sys для фильтров, чтобы они могли взаимодействовать с приложениями юзер-моды: Код: Код:
FltCreateCommunicationPort()Код: Код:
FilterConnectCommunicationPort()4.2.NtfsReparse Point, или точки повторной обработки «Reparse Point» представляет собой тип атрибута в файловых потоках NTFS. Если открыть спеку, то он числится в метаданных под номером Код:
0xC0На данный момент предусмотрено 2 типа точек RP – это пользовательские, и определённые в Microsoft. Последние используются диспетчером объектов для создания символических ссылок на файлы, а драйвером Mountvol.sys для создания точек монтирования томов жёсткого диска. Далее нас будут интересовать исключительно пользовательские «Third-Party Reparse Point». Пользовательскую точку определяет структура REPARSE_GUID_DATA_BUFFER с таким прототипом, которую нужно будет аргументом передать в функцию Код:
DeviceIoControl()Код: Код:
struct REPARSE_GUID_DATA_BUFFERКод:
0x4000Код:
0х8000https://forum.antichat.xyz/attachmen...d8bc44fb63.png Если мы хотим просканировать диск на наличие файлов с потоками RP, можно вызвать Код:
FindNextFile()Код:
DeviceIoControl()Код: Код:
FSCTL_SET_REPARSE_POINT = 0x000900a4Код: Код:
FltAddOpenReparseEntry()Для эксперимента создадим пустой файл с любым расширением (у меня TestFile.txt), и ещё один с произвольными данными, которые поместим в буфер потока RP (я записал строку HelloHackerLab). Теперь возьмём софтину «NTFS Stream Explorer», где можно быстро создать точку повторной обработки – по нашим данным она сама заполнит структуру REPARSE_GUID_DATA_BUFFER, и вызовет все нужные API. Вот скрин и галки, которые нужно в ней взвести: Что примечательно, система не может теперь получить доступ к новоиспечённому TestFile.txt – его нельзя ни открыть, ни удалить, ни скопировать. Единственно кому доступен файл, это утилита fsutil.exe из штатной поставки Win, которой необходимо передать ключ «reparsepoint» (принимает 2 аргумента: query и delete). Как видим, она исправно распарсила файл, а чтобы обратно получить доступ к нему, нужно просто удалить точку аргументом «delete»: https://forum.antichat.xyz/attachmen...80d9da135a.png Ещё одна уязвимость состоит в том, что начиная с Win10 в составе ОС появился новый управляющий код FSCTL_SET_REPARSE_POINT_EX =0x0009040C, который старые мини-фильтры не обрабатывают, ожидая только кода без суффикса(EX). В некоторых случаях это позволит приложению добавлять/удалять теги с флагом Microsoft 0x8000, что приведёт к получению файла с системной меткой, для обхода таких сторожей как WinDefender. 4.3. Уязвимость в значении высоты мини-фильтра Это класс ошибок, которые вызваны порядком следования мини-фильтров в стеке, на основе заданных им высот «Altitudes». Например, несоответствие высоты фильтра является причиной пропуска файловых событий шпионом «Process Monitor» из пакета SysinternalsSuite. Если запустить его и следом уже знакомую нам утилиту fltmc, то можно обнаружить, что драйвер мини-фильтра шпиона называется «ProcMon24.sys», и ему назначена высота 382.500, в то время как сторож LUAFV находится на более низком уровне 135.000. Как результат, фильтр LUAFV перехватывает все обращения шпиона ProcMon.exe к системным файлам, искажая логи последнего. Баг в том, что мы можем отсоединить от тома фильтр ProcMon24 командой «Detach», и снова присоединить его «Attach» на гораздо меньшей высоте чем LUAFV, например 20.000. Так шпион обойдёт сторожа, и в его логах мы получим больше интересной информации. Для справки по ключам введите fltmc attach. https://forum.antichat.xyz/attachmen...2edee1132b.png 5. Эпилог В узких кругах уязвимые драйвера называют LOL-драйверами от «Living Off The Land». Огромная их коллекция собрана здесь: LOLDrivers. Поиск багов в них это целая наука, на постижение которой можно потратить всю оставшуюся жизнь. Нужно знать не только общую архитектуру драйверов, но и пятой точкой уметь предсказывать все последующие шаги драйвера, после того-как пошлём ему пакет IRP для обработки. Отличным полигоном на начальном этапе может послужить 32-битная WinXP, которая не требует подписи драйверов, а потому любезно принимает на свой борт даже заведомо кривые субстанции для практической реализации атак. Здесь главное руку набить, после чего можно переселиться и на драйвера более актуальных систем. Ссылки по теме: Руководство по поиску багов https://www.ioactive.com/wp-content...gineering_and_Bug_Hunting_On_KMDF_Driver s.pdf Примеры мини-фильтров Windows-driver-samples/filesys/miniFilter at main · microsoft/Windows-driver-samples Разбор портов коммуникации Investigating Filter Communication Ports – Winsider Seminars & Solutions Inc. Справочник по кодам FSCTL Winioctl.h header - Win32 apps Дом.страница софта «NTFS Stream Explorer» NTFS Stream Explorer 2.2.0 |
Весьма интересная статья. Прочитал и сам много чего для себя подтянул.
|
| Время: 18:43 |