RootKit принципы и механизмы работы
Данный цикл статей посвящен достаточно актуальной в настоящий момент теме технологиям, применяемым разработчиками вредоносного программного кода. В последнее время появилось множество вредоносных программ, которые нельзя считать вирусами, поскольку они не обладают способностью к размножению. В этой публикации речь пойдет о RootKit, клавиатурных шпионах, троянских и шпионских программах.
Введение

В системе Windows термином «RootKit» принято называть программу, которая внедряется в систему и перехватывает системные функции или производит замену системных библиотек. Благодаря перехвату и модификации низкоуровневых API-функций такая программа достаточно хорошо маскирует свое присутствие в системе, защищая себя от обнаружения пользователем и антивирусным ПО. Кроме того, многие такие программы могут маскировать наличие в системе любых описанных в конфигурации RootKit процессов, папок и файлов на диске, ключей в реестре. Многие RootKit устанавливают в систему свои драйверы и сервисы (они, естественно, тоже являются невидимыми).
В последнее время угроза RootKit становится все более актуальной, так как разработчики вирусов, троянских программ и шпионского программного обеспечения начинают встраивать RootKit-технологии в свои вредоносные программы. Одним из классических примеров может служить троянская программа Trojan-Spy.Win32.Qukart, которая маскирует свое присутствие в системе при помощи RootKit-технологии (данная программа интересна тем, что ее RootKit-механизм прекрасно работает в Windows 95/98/Mе/2000/XP).
Для эффективной борьбы с RootKit необходимо понимание принципов и механизмов ее работы. Условно все RootKit-технологии можно разделить на две категории работающие в режиме пользователя (user mode) и в режиме ядра (kernel mode). RootKit первой категории основаны на перехвате функций библиотек пользовательского режима, а второй на установке в систему драйвера, осуществляющего перехват функций уровня ядра.
Далее в статье при описании методов перехвата функций речь идет именно о RootKit, однако нужно помнить, что рассмотренные методики универсальны и применяются множеством полезных программ и утилит.
Методы перехвата функций в режиме пользователя (user mode)

Перехват функций позволяет RootKit модифицировать результаты их работы. Например, перехват функции поиска файла на диске позволяет исключить из результатов поиска маскируемые файлы, а перехват функций типа ntdll.ZwQuerySystemInformation дает возможность замаскировать запущенные процессы и загруженные библиотеки.
Принцип вызова функции
Прежде чем перейти к рассмотрению принципов работы RootKit пользовательского режима, необходимо кратко описать принцип вызова функций, размещенных в DLL. Существует два базовых способа:
Независимо от метода связывания, системе необходимо знать, какие функции экспортирует DLL. Для этого у каждой DLL имеется таблица экспорта, в которой перечислены экспортируемые DLL функции, их номера (ординалы) и относительные адреса функций (RVA).
1. Модификация машинного кода прикладной программы
В этом случае модифицируется машинный код (рис. 2), отвечающий в прикладной программе за вызов той или иной функции API. Эта методика сложна в реализации, так как существует множество языков программирования и версий компиляторов, а программист может реализовать вызов функций Windows API различными методами. Но теоретически подобное возможно при условии, что внедрение будет идти в заранее заданную программу известной версии. В этом случае можно проанализировать ее машинный код и разработать перехватчик.
2. Модификация таблицы импорта
Данная методика описана в книге «Windows для профессионалов» Рихтера и является одной из классических. Идея методики проста: при внедрении RootKit находит в памяти системы таблицу импорта и исправляет адреса интересующих ее функций на адреса своих перехватчиков (естественно, она предварительно где-то запоминает правильные адреса). В момент вызова функции программа считывает ее адрес из таблицы импорта и передает по этому адресу управление. Методика универсальна, но у нее есть существенный недостаток (его хорошо видно на схеме, представленной на рис. 3) перехватываются только статически импортируемые функции. Но есть и плюс методика очень проста в реализации, причем есть масса примеров, демонстрирующих ее. Поиск таблицы импорта в памяти не представляет особой сложности, поскольку для этого существуют специализированные функции Windows API, позволяющие работать с образом программы в памяти. Исходный текст такого перехватчика на языке C занимает несколько листов печатного текста.
3. Перехват функций LoadLibrary и GetProcAddress
Перехват функций LoadLibrary и GetProcAddress может быть выполнен любым методом, в классическом варианте применяется модификация таблицы импорта (рис. 4). Идея этого тоже проста: если перехватить GetProcAddress, то при запросе адреса можно выдавать программе не реальные адреса интересующих ее функций, а адреса своих перехватчиков. Как и в методике 2, программа «не почувствует разницы». При вызове GetProcAddress она получает адрес и выполняет вызов функции. Но здесь есть и минус невозможно перехватить статически импортируемые функции.
4. Методика, сочетающая методики 2 и 3
В данной методике модифицируется таблица импорта, причем в обязательном порядке перехватываются функции LoadLibrary и GetProcAddress библиотеки kernel32.dll. В этом случае при вызове статически импортируемых функций искаженные адреса берутся из таблицы импорта, при динамическом определении адреса вызывается перехваченная функция GetProcAddress, которая возвращает адреса функций-перехватчиков. В результате у программы не остается шансов узнать правильный адрес функции (рис. 5).
5. Модификация программного кода функции
Данная методика сложнее в реализации, чем подмена адреса. Суть ее состоит в том, что RootKit находит в памяти машинный код интересующих ее функций и модифицирует его (рис. 6). При таком способе перехвата функции уже нет надобности в модификации таблицы импорта запущенных программ и передаче программам искаженных адресов при вызове GetProcAddress. Что касается вызова функции, то все остается как есть, но за одним исключением теперь уже по правильному адресу внутри правильной DLL находится машинный код RootKit.
Чаще всего вмешательство в машинный код перехватываемых функций минимально. В начале функции размещается не более двух-трех машинных команд, передающих управление основной функции-перехватчику. Для выполнения вызова модифицированных функций RootKit должна сохранить исходный машинный код для каждой модифицированной ею функции (естественно, сохраняется не весь машинный код функции, а измененные при перехвате байты). Именно такая методика перехвата реализована в широко известном HackerDefender и в библиотеке AFX RootKit (www.rootkit.com).
6. Модификация библиотек DLL на диске
Данная методика состоит в том, что системная библиотека модифицируется на диске. Методы модификации аналогичны вышеописанным, только изменения производятся не в памяти, а на диске. Эта методика не получила широкого распространения.
Перехват функций в режиме ядра (kernel mode)

Основное взаимодействие с ядром производится через библиотеку ntdll.dll, большинство функций которой являются «переходниками», обращающимися к ядру через прерывание INT 2Eh (отметим, что прикладной программе ничто не мешает напрямую вызвать это прерывание). Дальнейшее обращение к функциям ядра основано на структуре, именуемой KeServiceDescriptorTable (SDT), расположенной в исполняемом файле ntoskrnl.exe. SDT это таблица, содержащая адреса точек входа сервисов ядра NT. Описание функций и методик перехвата можно найти в книге «Недокументированные возможности Windows 2000» Свена Шрайбера, там же приведена схема взаимодействия, послужившая прототипом для приведенной здесь схемы. Упрощенно можно сказать, что для перехвата функций нужно написать драйвер, который произведет модификацию таблицы SDT. Перед модификацией драйверу необходимо сохранить адреса перехватываемых функций и записать в таблицу SDT адреса своих обработчиков. Данный метод чем-то напоминает перехват прерываний в MS DOS или описанную выше методику 2.
Этот метод часто называют перехватом Native API, и, естественно, он работает только в Windows NT (и соответственно Windows 2000/XP и Windows Server 2003). Следует отметить, что перехват Native API осуществляет не только RootKit существует множество полезных программ, перехватывающих функции при помощи правки SDT. В качестве примера можно привести популярную утилиту RegMon от SysInternals и программу Process Guard.
Вышеописанный метод является наиболее простым, но далеко не единственным. Существует еще ряд способов, в частности создание драйвера-фильтра, который может применяться как для решения задач мониторинга (классический пример утилита FileMon от SysInternals), так и для активного вмешательства в работу системы. В частности, драйвер-фильтр может использоваться для маскировки файлов и папок на диске. Принцип работы такого драйвера основан на манипуляциях с пакетами запроса ввода-вывода (IRP).
Методики обнаружения RootKit в системе

Заключение

В следующей статье цикла речь пойдет о клавиатурных шпионах их устройстве, принципах работы и методиках обнаружения.
Национальная библиотека им. Н. Э. Баумана
Bauman National Library
Персональные инструменты
Rootkit
Содержание
Определение
Руткит (англ. rootkit, то есть «набор root’а») — набор программных средств (например, исполняемых файлов, скриптов, конфигурационных файлов), для обеспечения маскировки объектов (процессов, файлов, директорий, драйверов), управления (событий, происходящих в системе), сбора данных (параметров системы). В системе Windows под термином «руткит» принято считать программу, которая внедряется в систему и перехватывает системные функции, или производит замену системных библиотек. Перехват и модификация низкоуровневых API функций в первую очередь позволяет такой программе достаточно качественно маскировать свое присутствие в системе, защищая ее от обнаружения пользователем и антивирусным ПО.
Кроме того, многие «руткиты» могут маскировать присутствие в системе любых описанных в его конфигурации процессов, папок и файлов на диске, ключей в реестре. Многие руткиты устанавливают в систему свои драйверы и сервисы (они естественно также являются «невидимыми»).
Классификация руткитов
Условно все руткит-технологии можно разделить на две категории:
Первая категория основана на перехвате функций библиотек пользовательского режима, вторая – на установке в систему драйвера, осуществляющего перехват функций уровня ядра. Также, руткиты можно классифицировать по принципу действия и по постоянству существования. По принципу действия:
В последнее время угроза RootKit становится все более актуальной, т.к. разработчики вирусов, троянских программ и шпионского программного обеспечения начинают встраивать RootKit-технологии в свои вредоносные программы. Одним из классических примеров может служить троянская программа Trojan-Spy.Win32.Qukart, которая маскирует свое присутствие в системе при помощи RootKit-технологии (данная программа интересна тем, что ее RootKit-механизм прекрасно работает в Windows 95\98\ME\2000\XP). Для эффективной борьбы с RootKit необходимо понимание принципов и механизмов его работы. Условно все RootKit-технологии можно разделить на две категории – работающие:
Первая категория RootKit основана на перехвате функций библиотек пользовательского режима, вторая – на установке в систему драйвера, осуществляющего перехват функций уровня ядра.
Методы перехвата API функций в режиме пользователя (user mode)
Перехват функций позволяет RootKit модифицировать результаты их работы – например, перехват функции поиска файла на диске позволяет исключить из результатов поиска маскируемые файлы, а перехват функций типа ntdll.ZwQuerySystemInformation позволяет замаскировать запущенные процессы и загруженные библиотеки.
Принцип вызова API функции
Перед рассмотрением принципов работы RootKit пользовательского режима необходимо кратко и упрощенно рассмотреть принцип вызова функций, размещенных в DLL. Известно два базовых способа:
Раннее связывание (статически импортируемые функции)
Этот метод основан на том, компилятору известен перечень импортируемых программой функций. Опираясь на эту информацию, компилятор формирует так называемую таблицу импорта EXE файла. Таблица импорта – это особая структура (ее местоположение и размер описываются в заголовке EXE файла), которая содержит список используемых программой библиотек и список импортируемых из каждой библиотеки функций. Для каждой функции в таблице имеется поле для хранения адреса, но на стадии компиляции адрес не известен. В процессе загрузки EXE файла система анализирует его таблицу импорта, загружает все перечисленные в ней DLL и производит занесение в таблицу импорта реальных адресов функций этих DLL. У раннего связывания есть существенный плюс – на момент запуска программы все необходимые DLL оказываются загруженными, таблица импорта заполнена – и все это делается системой, без участия программы. Но отсутствие в процессе загрузки указанной в его таблице импорта DLL (или отсутствие в DLL требуемой функции) приведет к ошибке загрузки программы. Кроме того, очень часто нет необходимости загружать все используемые программой DLL в момент запуска программы. На рисунке показан процесс раннего связывания – в момент загрузки происходит заполнение адресов в таблице импорта (шаг 1), в момент вызова функции из таблицы импорта берется адрес функции (шаг 2) и происходит собственно вызов функции (шаг 3);

Позднее связывание
Отличается от раннего связывания тем, что загрузка DLL производится динамически при помощи функции API LoadLibrary. Эта функция находится в kernel32.dll, поэтому если не прибегать к хакерским приемам, то kernel32.dll придется загружать статически. При помощи LoadLibrary программа может загрузить интересующую ее библиотеку в любой момент времени. Соответственно для получения адреса функции применяется функция kernel32.dll GetProcAddress. На рисунке шаг 4 соответствует загрузке библиотеки при помощи LoadLibrary и определению адресов при помощи GetProcAddress. Далее можно вызывать функции DLL (шаг 5), но естественно при этом таблица импорта не нужна. Чтобы не вызывать GetProcAddress перед каждым вызова функции из DLL программист может однократно определить адреса интересующих его функций и сохранить их в массиве или некоторых переменных. Независимо от метода связывания системе необходимо знать, какие функции экспортирует DLL. Для этого у каждой DLL имеется таблица экспорта – таблица, в которой перечислены экспортируемые DLL функции, их номера (ординалы) и относительные адреса функций (RVA).
Модификация машинного кода прикладной программы
В этом случае модифицируется машинный код, отвечающий в прикладной программе за вызов той или иной функции API. Это методика сложна в реализации, т.к. существует множество языков программирования, версий компиляторов и программист может реализовать вызов API функций различными методиками. Но теоретически подобное возможно при условии, что внедрение будет идти в заранее заданную программу известной версии. В этом случае можно проанализировать ее машинный код и разработать перехватчик.
Модификация таблицы импорта
Перехват функций LoadLibrary и GetProcAddress
Перехват функций LoadLibrary и GetProcAddress может быть выполнен любым методом, в классической реализации применяется методика 2 – модификация таблицы импорта. Идея методики проста – если перехватить GetProcAddress, то при запросе адреса можно выдавать программе не реальные адреса интересующих ее функций, а адреса своих перехватчиков. Как и в методе 2 программа «не почувствует» разницы. При вызове GetProcAddress она получает адрес и выполняет вызов функции. У данного метода есть минус – он не позволяет перехватить статически импортируемые функции.
Метод, сочетающий методику 2 и 3
В данной методике модифицируется таблица импорта, причем в обязательном порядке перехватываются функции LoadLibrary и GetProcAddress библиотеки kernel32.dll. В этом случае при вызове статически импортируемых функций искаженные адреса берутся из таблицы импорта, при динамическом определении адреса вызывается перехваченная функция GetProcAddress, которая возвращает адреса функций-перехватчиков. В результате у программы не остается шансов узнать правильный адрес функции.
Модификация программного кода API функции
Данные метод сложнее в реализации, чем подмена адреса. Методика состоит в том, что RootKit находит в памяти машинный код интересующих его функций API и модифицирует его. При таком методе перехвата функции уже нет надобности в модификации таблицы импорта запущенных программ и передаче программам искаженных адресов при вызове GetProcAddress. С точки зрения вызова функции все остается «как есть» за одним исключением – теперь уже по «правильному» адресу внутри «правильной» DLL находится машинный код RootKit. Чаще всего вмешательство в машинный код перехватываемых функций минимально. В начале функции размещается не более 2-3 машинных команд, передающих управление основной функции-перехватчику. Для выполнения вызова модифицированных функций RootKit должен сохранить исходный машинный код для каждой модифицированной им функции (естественно, сохраняется не весь машинный код функции, а измененные при перехвате байты). [1]
Модификация библиотек DLL на диске
Данная методика состоит в том, что системная библиотека модифицируется на диске. Методы модификации аналогичны описанным выше, только изменения производятся не в памяти, а на диске. Подобная методика не получила широкого распространения.
Перехват функций в режиме ядра (kernel mode)
Для понимание типовой для методики перехвата функций в режиме ядра следует рассмотреть принципы взаимодействия библиотек пользовательского режима и ядра. Рассмотрим это взаимодействие на упрощенной схеме:

Основное взаимодействие с ядром производится через ntdll.dll, большинство функций которой являются переходниками, обращающимся к ядру через прерывание INT 2Eh (следует заметить, что прикладной программе ничто не мешает напрямую вызывать INT 2Eh). Дальнейшее обращение к функциям ядра основана на структуре, именуемой KeServiceDescriptorTable (или сокращенно SDT), расположенной в ntoskrnl.exe. SDT – это таблица, содержащая адреса точек входа сервисов ядра NT. Описание функций и методик перехвата можно найти в книге Свена Шрайбера «Недокументированные возможности Windows 2000», там же приведена схема взаимодействия, послужившая прототипом для приведенной здесь схемы. Упрощенно можно сказать, что для перехвата функций необходимо написать драйвер, который произведет модификацию таблицы SDT. Перед модификацией драйверу необходимо сохранить адреса перехватываемых функций и записать в таблицу SDT адреса своих обработчиков. Данный метод чем-то напоминает перехват прерываний в MSDOS или описанную выше методику 2. Этот метод часто называют перехватом Native API и естественно он работает только в NT (и соответственно W2K, XP, W2003). Следует отметить, что перехват Native API осуществляют не только руткиты – существует масса полезных программ, перехватывающих функции при помощи правки SDT – в качестве примера могут служить популярная утилита RegMon от SysInternals или программа Process Guard. Следует отметить, что описанный метод является наиболее простым, но далеко не единственным. Существует еще ряд способов, в частности создание драйвера-фильтра. Драйвер-фильтр может применяться как для решения задач мониторинга (классический пример – утилита FileMon от SysInternals), так и для активного вмешательства в работу системы. В частности, драйвер-фильтр может применяться для маскировки файлов и папок на диске. Принцип работы такого драйвера основан на манипуляциях с пакетами запроса ввода-вывода (IRP).
Методики обнаружения RootKit в системе
Базовые методики поиска RootKit:
Антируткит
Что такое руткиты и чем они опасны?
Возможно, вы не раз столкнулись с некоторыми формами вредоносных программ во время серфинга в интернете. Существует один тип такой программы, самый неприятный по сравнению с другими — руткит. Его очень трудно удалить и обнаружить. Что такое руткиты и чем они опасны мы расскажем в данной статье.
Что делают руткиты?
Руткит — это набор вредоносных программ, скрытых в вашем компьютере и предназначенных для проникновения в места, обычно недоступных неавторизованному пользователю, и получения контроля над системой. Хакеры могут использовать уязвимости в программном обеспечении для удаленного управления им.
Руткиты очень трудно обнаружить, так как они используют сложные схемы маскировки, чтобы скрыть свое местонахождение. Он может прятаться на уровне ядра, которое управляет всей системой, или маскироваться под другое ПО и даже приложения. Руткиты также могут загружаться с ОС и перехватывать ее связь.
Помимо ноутбука или настольного компьютера, руткит также может быть нацелен на устройства IOT. Он имеет высокий уровень опасности и трудно удаляется.
На видео: Что такое руткит и как его удалить?
Использование руткитов
Что хакеры могут сделать с руткитами:
Но руткиты также могут быть использованы и для хороших целей, таких как обнаружение хакерских атак, защиты программного обеспечения безопасности или защиты ноутбуков от кражи, позволяя осуществлять их мониторинг в случае кражи.
Виды руткитов
Как заражаются устройства?
Руткит может инфицировать систему следующими способами:
Как удалить руткиты?
К счастью, руткитные атаки сегодня не очень распространены, так как различные системы защиты ядра стали более продвинутыми. Но если устройство уже заражено, то процесс удаления может быть довольно сложным. Его можно удалить:
Как предотвратить появление руткитов?
Лучшее лекарство от всех типов вредоносных программ — это профилактика. Вы должны делать следующее, чтобы свести к минимуму возможность заражения руткитами:











