Меняем Integrity Level процесса из ядра

dxcat

Опять случился большой перерыв между публикациями в блоге, но, благодаря настойчивости dx'a, который в данный момент занят улучшением его библиотеки для работы с PE-файлами и продажей новой версии обфускатора PHP, в блоге все-таки появится новый пост. На этот раз он будет посвящен реализации очередного тривиального драйвера, который будет получать уведомления о новых процессах, запускаемых в системе и понижать уровень целостности (integrity level) заданного процесса до низкого.


В качестве заготовки я воспользуюсь фрагментами кода из моей старой публикации. Но давайте по порядку. Для начала нам необходимо как-то получать уведомления о процессах, запускаемых в ОС. Самый простой способ - воспользоваться функцией PsSetCreateProcessNotifyRoutineEx (я умышленно использую функцию, которая появилась в Windows только начиная с Vista, серьезно, сколько можно заниматься поддержкой старых, неактуальных версий ОС, даже поддержка относительно новой Windows 7 заканчивается в 2015 году, а уж на XP закладываться... let it go).
Итак, давайте уже напишем немного кода:

Что делает этот код: в процедуре DeployProcessHook мы инициализируем глобальный мьютекс (он будет использоваться при работе с переменной ProcessName, чтобы не возникало конфликтов), регистрируем процедуру HookRoutine, чтобы она получала уведомления о новых процессах и инициализируем глобальную переменную ProcessName, которая будет содержать название процесса, для которого будет выставляться low integrity level. В RemoveProcessHook мы совершаем противоположные действия.
Теперь рассмотрим HookRoutine, которая получает информацию о создаваемых процессах и принимает решение об установке low integrity.

Логика работы крайне примитивна и едва ли нуждается в детальном пояснении. Таймаут на ожидание мьютекса я поставил на случай, если драйвер будет обрабатывать пользовательский IOCTL неоправданно долго (даже не уверен, имеет ли смысл эта конструкция здесь).
Буду слегка непоследовательным и приведу код одной вспомогательной функции, которая использовалась выше, а потом вернусь к основной логике.

GetFileName необходима для ивзлечения имени запускаемого файла из полного пути, который мы получаем из структуры PS_CREATE_NOTIFY_INFO, находясь в HookRoutine.
Возвращаемся к основной логике:

SetLowIntegrity получает хендл токена запускаемого процесса и передает в TuneTokenIntegrity, которая, в свою очередь, выставляет low integrity level. Кстати, много полезных примеров по взаимодействию с процессами можно посмотреть в исходном коде Process Hacker, собственно, код TuneTokenIntegrity подсмотрен в них.
Осталась последняя вспомогательная функция, которая устанавливает значение глобальной переменной ProcessName, которую я упоминал ранее.

Возможно у кого-то возник вопрос, что такое LOG. Это просто вспомогательный макрос для логирования. Единственная цель - возможность отключить логирование, не комментируя кучи строк.

Также приведу код DriverEntry и прочих обязательных процедур, а также простой программы для взаимодействия с драйвером. Комментировать не буду, так как примитивно, да и код упоминался в прошлой статье.
DriverEntry и прочее:

Простое приложение:

Упомяну несколько важных моментов: при линкове драйвера необходимо указать параметр /integritycheck. При отсутствии параметра драйвер не удастся загрузить, также не забывайте, что для тестирования необходимо включить TESTSIGNING и подписать драйвер каким-нибудь сертификатом, например, так:

Подробнее про процесс подписи можно почитать в MSDN. В проект для MSVC 2013, который можно скачать по ссылке в конце статьи, я включил тестовый сертификат и добавил post-build event для подписывания драйвера.

Наконец, загрузим драйвер в тестовой среде и посмотрим, работает ли он. По умолчанию Notepad запускается с medium integrity level:

default_integrity
И с low integrity, при наличии нашего драйвера в системе:

driver_run

Вроде все работает.

Проект для MSVC 2013: скачать

Меняем Integrity Level процесса из ядра: 9 комментариев

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

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