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

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

Иван Скляров

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


Скрытие файлов

Содержимое директории считывается системным вызовом getdents64 (или просто getdents, в зависимости от версии ядра). Это можно узнать при помощи утилиты strace. Этот вызов использует функция readdir(), которая читает содержимое директорий. Результат getdents64 сохраняется в виде списка структур struct dirent, а сам вызов возвращает длину всех записей в каталоге:

struct dirent64 {

int d_ino1, d_ino2;

int d_off1, d_off2;

unsigned short d_reclen;

unsigned char d_type;

char d_name[0];

} *dirp2, *dirp3;

Нам интересны два поля этой структуры: d_reclen (размер записи) и d_name (имя файла). Таким образом, для того чтобы спрятать запись о файле, нам достаточно подменить вызов getdents64, затем отыскать в списке полученных структур соответствующую запись и удалить ее. Исходный код hide_file.c с комментариями ищи на DVD.

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

Скрытие каталогов и процессов

Для скрытия каталогов и процессов можно задействовать один и тот же метод. Я прочел о нем в статье «Sub proc_root Quando Sumus (Advances in Kernel Hacking)» из Phrack #58-06. В этом методе не требуется перехватывать системные вызовы. Суть его заключается в том, что Linux-устройства и каталоги могут рассматриваться как файлы. Каждый файл (каталог, устройство) представлен в ядре структурой file. Она содержит поле f_op, которое, в свою очередь, указывает на структуру file_operations. Последняя используется для хранения указателей на функции, производящие различные стандартные операции с файлом, такие как read(), write(), readdir(), ioctl() и т.д. Определения обеих структур - file и file_operations - ты можешь увидеть в файле linux/fs.h. Если в структуре file_operations подменить указатели на функции или подставить вместо них NULL (это будет означать, что данная функция не реализована), то можно изменить поведение конкретного файла (каталога, устройства). Так как нам требуется скрывать каталоги, то удобнее всего подменить указатель на функцию readdir(), который представлен в структуре file_operations следующим образом:

int (*readdir) (struct file *, void *, filldir_t);

Функция readdir() реализует системные вызовы readdir(2) и getdents(2) для каталогов и игнорируется для обычных файлов.

Мы можем подставить вместо указателя NULL, но тогда вообще не будут отображаться никакие каталоги. В рутките же требуется прятать только отдельные каталоги, поэтому мы будем подменять этот указатель указателем на свою функцию, которая будет отслеживать заданный каталог.

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