Реферат: Руткиты

1.Раннее связывание (статически импортируемые функции).

Этот метод основан на том, компилятору известен перечень импортируемых программой функций. Опираясь на эту информацию, компилятор формирует так называемую таблицу импорта EXE файла. Таблица импорта – это особая структура (ее местоположение и размер описываются в заголовке EXE файла), которая содержит список используемых программой библиотек и список импортируемых из каждой библиотеки функций. Для каждой функции в таблице имеется поле для хранения адреса, но на стадии компиляции адрес не известен. В процессе загрузки EXE файла система анализирует его таблицу импорта, загружает все перечисленные в ней DLL и производит занесение в таблицу импорта реальных адресов функций этих DLL. У раннего связывания есть существенный плюс – на момент запуска программы все необходимые DLL оказываются загруженными, таблица импорта заполнена – и все это делается системой, без участия программы. Но отсутствие в процессе загрузки указанной в его таблице импорта DLL (или отсутствие в DLL требуемой функции) приведет к ошибке загрузки программы. Кроме того, очень часто нет необходимости загружать все используемые программой DLL в момент запуска программы. На рисунке показан процесс раннего связывания – в момент загрузки происходит заполнение адресов в таблице импорта (шаг 1), в момент вызова функции из таблицы импорта берется адрес функции (шаг 2) и происходит собственно вызов функции (шаг 3);

Рис.2 Раннее связывание

2.Позднее связывание.

Отличается от раннего связывания тем, что загрузка DLL производится динамически при помощи функции API LoadLibrary. Эта функция находится в kernel32.dll, поэтому если не прибегать к хакерским приемам, то kernel32.dll придется загружать статически. При помощи LoadLibrary программа может загрузить интересующую ее библиотеку в любой момент времени. Соответственно для получения адреса функции применяется функция kernel32.dll GetProcAddress. На рисунке шаг 4 соответствует загрузке библиотеки при помощи LoadLibrary и определению адресов при помощи GetProcAddress. Далее можно вызывать функции DLL (шаг 5), но естественно при этом таблица импорта не нужна. Чтобы не вызывать GetProcAddress перед каждым вызова функции из DLL программист может однократно определить адреса интересующих его функций и сохранить их в массиве или некоторых переменных.

Независимо от метода связывания системе необходимо знать, какие функции экспортирует DLL. Для этого у каждой DLL имеется таблица экспорта – таблица, в которой перечислены экспортируемые DLL функции, их номера (ординалы) и относительные адреса функций (RVA).

4.2 Модификация машинного кода прикладной программы.

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

Рис.3 Модификация машинного кода прикладной программы

4.3 Модификация таблицы импорта

Данная методика описана в книге Рихтера и является одной из классических. Идея метода проста – RootKit находит в памяти таблицу импорта программы и исправляет адреса интересующих его функций на адреса своих перехватчиков (естественно, он предварительно где-то у себя запоминает правильные адреса). В момент вызова API функции программа считывает ее адрес из таблицы импорта и передает по этому адресу управление. Методика универсальна, но у нее есть существенный недостаток (и его хорошо видно на схеме) - перехватываются только статически импортируемые функции. Но есть и плюс – методика очень проста в реализации и есть масса примеров, демонстрирующих ее реализацию. Поиск таблицы импорта в памяти не представляет особой сложности, поскольку для этого существуют специализированные API функции, позволяющие работать с образом программы в памяти. Исходный текст такого перехватчика на языке C занимает несколько листов печатного текста;

Рис. 4 Модификация таблицы импорта

4.4 Перехват функций LoadLibrary и GetProcAddress

Перехват функций LoadLibrary и GetProcAddress может быть выполнен любым методом, в классической реализации применяется методика 2 – модификация таблицы импорта. Идея методики проста – если перехватить GetProcAddress, то при запросе адреса можно выдавать программе не реальные адреса интересующих ее функций, а адреса своих перехватчиков. Как и в методе 2 программа «не почувствует» разницы. При вызове GetProcAddress она получает адрес и выполняет вызов функции. У данного метода есть минус – он не позволяет перехватить статически импортируемые функции;

Рис. 5 Перехват функций LoadLibrary и GetProcAddress

4.5 Метод, сочетающий методику 2 и 3

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

Рис. 6 Метод сочетающий Перехват функций LoadLibrary и GetProcAddress и модификацию таблицы импорта

4.6 Модификация программного кода API функции.

Данные метод сложнее в реализации, чем подмена адреса. Методика состоит в том, что RootKit находит в памяти машинный код интересующих его функций API и модифицирует его. При таком методе перехвата функции уже нет надобности в модификации таблицы импорта запущенных программ и передаче программам искаженных адресов при вызове GetProcAddress. С точки зрения вызова функции все остается «как есть» за одним исключением – теперь уже по «правильному» адресу внутри «правильной» DLL находится машинный код RootKit.

Рис.7. Модификация программного кода API функции.

Чаще всего вмешательство в машинный код перехватываемых функций минимально. В начале функции размещается не более 2-3 машинных команд, передающих управление основной функции-перехватчику. Для выполнения вызова модифицированных функций RootKit должен сохранить исходный машинный код для каждой модифицированной им функции (естественно, сохраняется не весь машинный код функции, а измененные при перехвате байты). Именно такая методика перехвата реализована в широко известном HackerDefender и библиотеке AFX Rootkit (www.rootkit.com).

4.7. Модификация библиотек DLL на диске

К-во Просмотров: 371
Бесплатно скачать Реферат: Руткиты