Отключение проверки целостности ядра 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\. Важно понимать, что по приведенной в данной статье методике необходимо пропатчить ту версию ядра, которая актуальна именно для вашей системы, поскольку простая модификация файла ntoskrnl.exe не всегда дает результат. В дополнение, сигнатуры кода в разных версиях ядра могут отличаться, тем не менее, я не спроста привожу в статье части исходного кода изменяемых функций, дабы по аналогии можно было всегда найти требуемый участок кода.

Функция SepInitializeCodeIntegrity

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

Функция 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 не будет опубликован. Обязательные поля помечены *