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

В борьбе с журнальными бестиями

Иван Скляров (www.sklyaroff.ru)

Хакер, номер #078, стр. 078-100-4


В заголовочный файл я включаю файл lastlog.h "#include <lastlog.h>". Но как я говорил ранее, в системе Linux он не обязателен, ибо является ссылкой на utmp.h. Также я на всякий случай определяю пути к лог-файлам (хотя обычно UTMP_FILE и WTMP_FILE определены в utmp.h):

#define UTMP_FILE "/var/run/utmp"

#define WTMP_FILE "/var/log/wtmp"

#define LASTLOG_FILE "/var/log/lastlog"

В программе мной создано две основных функции: dead_uwtmp() предназначена для очистки файлов utmp и wtmp, а функция dead_lastlog() очищает lastlog. Поиск в логах структуры для очистки производится по имени пользователя. В полноценной утилите также неплохо сделать поиск по названию удаленного хоста и имени терминала. Основным кодом в функции dead_uwtmp() является следующий участок:

while (read(fd, &pos, dist) == dist)

{

if (!strncmp(pos.ut_name, name_arg, sizeof(pos.ut_name)))

{

bzero(&pos, dist);

if (lseek(fd, -dist, SEEK_CUR) != -1)

write (fd, &pos, dist);

}

}

Где pos определено как struct utmp pos, а dist = sizeof(struct utmp).

Здесь последовательно считываются структуры из файла с помощью read(), и как только обнаруживается совпадение с именем пользователя (ut_name), подготавливается чистая структура, целиком заполненная нулями при помощи bzero(). Чистая структура записывается на место существующей функцией write(), для чего на начало модифицируемой структуры предварительно устанавливается файловый указатель с помощью lseek().

В структуре lastlog отсутствует поле с именем пользователя, поэтому для модификации этого лога нужен другой подход, отличный от utmp и wtmp. В решении задачи поможет следующий момент — все записи в файле lastlog отсортированы по UID. Поэтому в функции dead_lastlog() по имени пользователя определяется его UID с помощью стандартной функции getpwnam(). Затем производится очистка найденной структуры в файле lastlog с помощью следующих строк (в OpenBSD второй аргумент lseek() следует приводить к типу off_t — прим. ред.):

lseek(fd, (long)pwd->pw_uid * dist, 0);

bzero((char *)&pos, dist);

write(fd, (char *)&pos, dist);

Как видишь, программа довольно проста и в совокупности занимает всего около 80 строк. В одном архиве с этим клинером я положил пример еще одного самодельного клинера, который скрывает хакера от утилит w, who и last, но при этом не затирает нулями структуру utmp. Я заметил, что достаточно поменять тип записи ut_type с USER_PROCESS на DEAD_PROCESS, как администраторские утилиты перестанут отображать такую запись на экране. Этот способ хорош тем, что затрудняет обнаружение изменений с помощью различных IDS. К сожалению, не во всех системах структура utmp имеет поле ut_type, но в Linux (в отличие от FreeBSD) она точно есть.

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