Отключение проверки целостности ядра ntoskrnl.exe

Метки:  , , , , , , ,

Никогда не интересовались каким именно образом ядро Windows проверяет собственный код на попытку внесения изменений? Ведь современные операционные системы должны иметь механизмы защиты и причин для этого достаточно, одни руткиты чего стоят. Например, в 32-разрядной системе (x86) Windows, начиная с версии Vista, вполне официально присутствуют опции включения/отключения проверки целостности компонентов, участвующих в процессе запуска операционной системы: это флаги загрузки ENABLE_INTEGRITY_CHECKS и TESTSIGNING. В этой же версии в ядре появилась новая функция, носящая название SepInitializeCodeIntegrity и фактически являющаяся контейнером (оберткой) для передачи управления функции CiInitialize (экспортируемой библиотекой ci.dll). В случае, когда проверка целостности включена в операционной системе, SepInitializeCodeIntegrity внутри себя выполняет вызов функции CiInitialize, при отключенной же проверке обращения к функциям данной библиотеки не происходит. Помимо своего собственного кода, ядро ntoskrnl.exe производит проверку некоторых других критичных для системы модулей: драйверов этапа загрузки (флаг BOOT_START), системных драйверов (флаг SYSTEM_START), и драйверов, подгружаемых уже в процессе функционирования операционной системы (флаги DEMAND_START, AUTO_START). Целостность кода загружаемых ядром исполняемых образов проверяется двумя ядерными функциями:

  • Функция SeValidateImageHeader (контейнер к функции CiValidateImageHeader из ci.dll) -- вызывается на этапе отображения исполняемого образа в адресное пространство ядра.
  • Функция SeValidateImageData (контейнер к функции CiValidateImageData из ci.dll) -- вызывается на стадии загрузки модуля ядра.

Мониторинг в процессе функционирования операционной системы (непрерывный опрос на предмет изменений секций кода драйверов ядра) осуществляются через дополнительный механизм PatchGuard и некоторые функции библиотеки ci.dll, о которых в данной статье речи не идет.

Все эти проверки крайне осложняют жизнь исследователя, поэтому в данной статье мы рассмотрим один из методов отключения проверки целостности ядра ntoskrnl, путем внесения изменений непосредственно в исходный код ядра.
Хотелось бы обратить особое внимание на то, что на этапе работы модуля winload.exe, он загружает одну из версий ядра, в зависимости от ряда условий:

  • ntoskrnl.exe -- (1 ядро ЦП);
  • ntkrnlmp.exe -- (N ядер ЦП, SMP);
  • ntkrnlpa.exe -- (1 ядро ЦП, PAE);
  • ntkrpamp.exe -- (N ядер ЦП, SMP, PAE);

Все эти разновидности ядра для различных аппаратных конфигураций располагаются в директории %SystemRoot%\System32\. Поэтому, по аналогии с приведенной в данной статье методикой, необходимо будет пропатчить ту версию ядра, которая актуальна именно для вашей системы. Сигнатуры кода, конечно же, могут слегка отличаться, тем не менее стоит действовать по аналогии, поскольку описать все возможные варианты я не имею возможности.

Функция SepInitializeCodeIntegrity

заменяем первый байт опкодом EB (jmp ...).

Функция SeValidateImageHeader

заменяем опкодами 90 90 (nop+nop)

Функция SeValidateImageData

заменяем опкодами 90 90 (nop+nop).

После всех приведенных выше модификаций кода ядра, фактически производится отключение проверки целостности ядра ntoskrnl.exe, ядро перестает реагировать на вносимые в исполняемый модуль изменения. Тем не менее, описанное выше решение несколько своеобразно, поскольку фактически создает видимость установленных опций отключения проверки целостности и выставленного тестового режима работы операционной системы, поэтому для 64-битных версий наверняка потребуется доработка алгоритма!!

После проделанных изменений не забудьте пересчитать и заменить контрольную сумму (поле Checksum заголовка PE) изменяемых файлов. Осуществляется это посредством утилиты LordPE или любого аналогичного редактора PE-модулей.
Но на этом отключения проверки целостности не оканчивается. После описанной модификации ядра, система при загрузке "валится" в синий экран с ошибкой BSOD 0000008E в функции I_PEVerityBootDrivers где-то в недрах ci.dll. Поэтому необходимо выполнить еще один этап модификации, а именно пропатчить код библиотеки ci.dll, о чем мы поговорим позже.

Добавить комментарий

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