Артем Баранов
Случалось ли вам замечать, что в системе «живет» посторонний процесс. Но
ни диспетчер задач, ни другие программы не могут его показать. Может быть,
процесс скрывается и от них? Каковы методики скрытия в режиме ядра?
В последнее время в мире NT получает все большее распространение технология руткитов.
По сути, руткит (rootkit) представляет собой технологию, предназначение которой
скрывать что-либо. Под технологией руткитов обычно понимают программу, которая
«документированно» или нет использует перехват API-вызовов для фильтрации
возвращаемых результатов системных функций. В предыдущей статье (см. №10 за
2006 г.) давалась вводная информация, а также были рассмотрены алгоритмы работы
руткитов пользовательского режима. В данной статье внимание уделено алгоритмам
работы руткитов режима ядра.
Напомню, что руткиты режима ядра функционируют на
нулевом кольце и имеют полный доступ к области памяти ядра NT, со всеми
вытекающими отсюда последствиями.
Например, руткит может модифицировать структуры
данных Windows и тем самым скорректировать поведение ядра для достижения
заданных целей: маскировка файлов, процессов, сетевых соединений. В статье
описываются техники, используемые в современных руткитах режима ядра, включая fu
и Shadow Walker. Также описаны утилиты, с использованием которых можно выявлять
скрытые руткитами объекты.
Классификация
Для скрытия в системе каких-либо объектов руткиты либо
перехватывают системные сервисы ядра, аналогично тому, как это делают руткиты
пользовательского режима для DLL, либо модифицируют структуры данных ядра. В
соответствии с таким подходом руткиты делятся на две следующие группы:
n модифицирующие путь выполнения потока (modify execution
path);
n модифицирующие объекты ядра (directly kernel object
manipulation, DKOM).
Первые реализуются с
использованием следующих методов:
n перехват функций через SSDT (таблица
диспетчеризации системных сервисов);
n перехват прерываний;
n изменение первых машинных команд
перехватываемой функции на jmp;
n изменение указателей в объектах ядра, например KTHREAD.pService
DescriptorTable.
Руткиты, относящиеся к первому типу, заставляют
поток, вызвавший системный сервис, отработать код руткита. Когда код руткита
получает управление, он вызывает настоящий системный сервис по указателю,
отфильтровывает данные и возвращает результат.
Второй тип руткитов менее заметен, т.к. код руткита
напрямую не выполняется. Руткит модифицирует одну (или несколько) структур
данных ядра. Таким образом заставляя системную функцию работать с ложным
объектом (или очередью объектов). Такие руткиты воздействуют на работу ядра
косвенно.
Рассмотрим каждый из методов более подробно.