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

Хакнутый Syslog на страже порядка

Will Barrent & Andrey Matveev

Xakep, номер #067, стр. 067-052-1

(andrushock@real.xakep.ru) & (barrent@hotbox.ru)

Защищаем систему журналирования

Мы так много пишем о взломе Unix-like систем, что ты уже, наверное, наизусть выучил несколько стандартных "ScriptKiddies" схем: изучение сервисов системы, поиск багов, компиляция эксплойта, рутшелл; или: получение локальных привилегий, изучение системы, поиск уязвимостей, рутшелл. Сегодня предлагаю все наши усилия направить на то, чтобы запутать взломщика еще на стадии изучения системы и направить его по заведомо ложному пути, не предоставляя достоверных сведений о конфигурации основных сервисов. Для этого мы самостоятельно изменим некоторые функции ядра.

Разборки с сисколами

Для начала нужно научиться скрывать куски файловой системы, проще говоря, создавать "невидимые" директории. Это очень полезная фишка, и она не раз тебе пригодится. Обычно такие вещи делает сам взломщик, пытающийся закрепиться на порутанной тачке. Теперь же мы поменяемся с ним местами. Итак, пораскинем мозгами, что же нужно сделать... Самое простое, что приходит в голову - расковырять исходник утилиты ls и внести туда необходимые изменения. Но это как раз и не входит в наши планы: во-первых, кроме ls существует масса других способов посмотреть содержимое директории, например, find, а во-вторых, это не элитно ;). Мы модифицируем ядро! Что-то мне подсказывает, что твои отношения с внутренностями ядра FreeBSD носят далеко не интимный характер, поэтому постараюсь растолковать все поподробнее. Все программы, показывающие содержимое директории, используют одну и ту же системную функцию getdirentries(2), которая специфицирована следующим образом: int getdirentries(int fd, char *buf, int nbytes, long *basep), где fd - файловый дескриптор, buf - указатель на буфер, куда складываются записи с содержимым директории, nbytes - размер буфера, basep - текущая позиция указателя.

Таким образом, мы можем занести в буфер сведения о содержимом директории в виде массива структур dirent (сокращение от "directory entry"). Чтобы получить описание этой структуры, давай посмотрим на системный заголовочный файл /usr/include/sys/dirent.h:

Структура dirent в комментариях

struct dirent {

__u_int32_t d_fileno; /* номер файла */

__u_int16_t d_reclen; /* длина записи */

__u_int8_t d_type; /* тип файла */

__u_int8_t d_namlen; /* длина имени файла */

char d_name[MAXNAMLEN + 1]; /* имя файла */

}

Со значением константы MAXNAMLEN все просто: она определена в этом же файле и равна 255. Все записи в буфере не обязательно идут подряд, часто между ними бывают промежутки. Именно поэтому нам необходима длина записи d_reclen. Зачем так хитро сделано, знают только писавшие BSD студенты-наркоманы из института Berkeley ;). Теперь пора посмотреть на код этого вызова. Берем в зубы любимый текстовый редактор (фанаты лямбда-исчисления и Лиспа могут использовать Emacs) и открываем файл /usr/src/sys/kern/vfs_syscalls.c, в котором свалены в кучу все системные вызовы, связанные с файловой системой. Находим вот это место:

int

getdirentries(p, uap)

struct proc *p;

register_t struct getdirentries_args *uap;

Содержание  Вперед на стр. 067-052-2
ttfb: 3.2479763031006 ms