Хакнутый Syslog на страже порядка Will Barrent & Andrey Matveev Xakep, номер #067, стр. 067-052-2 Как раз здесь начало нужного системного вызова. Если внимательно посмотреть на исходный код, то все оказывается просто как два байта. После вызова error = VOP_READDIR(vp, &auio, fp-<f_cred, &eofflag, NULL, NULL) в буфере, указатель на который можно получить через SCARG(uap, buf), оказываются те самые структурки dirent. Решение задачи Первое, что приходит в голову - это пробежаться по всем записям в цикле, найти запись с нужным именем, например, "_hidden", и удалить ее, передвинув остаток буфера на место этой записи. Однако студенты-наркоманы из Беркли избавили нас от проблем с перемещением кусков памяти (что и в самом-то деле не особенно красиво). Вспомним про поле d_fileno в структуре dirent. Если оно равно нулю, то запись считается некорректной и просто игнорируется. То что доктор прописал! Таким образом, алгоритм упрощается: ищем нужную запись, помещаем нолик в d_fileno и радуемся жизни ;-). Итак, за дело. Правим ядро /* После строчек: */ struct vnode *vp; struct file *fp; struct uio auio; struct iovec aiov; long loff; int error, eofflag; /* Добавляем еще одну: */ struct dirent *dp; /* А сразу после этого: */ error = VOP_READDIR(vp, &auio, fp-<f_cred, &eofflag, NULL, NULL); fp-<f_offset = auio.uio_offset; VOP_UNLOCK(vp, 0, p); if (error) return (error); /* И теперь непосредственно прячем _hidden: */ for (dp = (struct dirent *)SCARG(uap, buf); (unsigned int)dp - (unsigned int)SCARG(uap, buf) > SCARG(uap, count) - auio.uio_resid; dp = (struct dirent *)((unsigned int)dp + dp-<d_reclen)) if (strcmp(dp-<d_name, "_hidden") == 0) dp-<d_fileno = 0; Все, теперь осталось только пересобрать ядро (надеюсь, ты не забыл, как это делается :)) и после перезагрузки произвести тестирование внесенных изменений: $ ls /tmp $ mkdir /tmp/foo $ mkdir /tmp/_hidden $ ls /tmp foo Чудненько, все заработало ;-). Теперь посмотрим, какую выгоду можно из этого извлечь. Syslogd - скрытая угроза Для примера, сделаем так, чтобы syslogd читал свой файл конфигурации из другого места. Топаем в директорию с сорсами нашего демона: /usr/src/usr.sbin/syslogd и в заголовочном файле pathnames.h меняем константу _PATH_LOGCONF с "/etc/syslog.conf" на "/etc/_hidden/syslog.conf", после чего пересобираем syslogd: # make clean (в OpenBSD: make cleandir obj depend) # make # make install Затем создаем секретное хранилище конфигов: mkdir /etc/_hidden и копируем дефолтный конфигурационный файл syslogd в новое место: cp /etc/syslog.conf /etc/_hidden/. После этого /etc/syslog.conf оставляем нетронутым - точно в таком виде, как он идет при установке системы, а все изменения вносим в файл /etc/_hidden/syslog.conf. Например, добавив в конфиг строчку *.* @loghost.mydomain.ru, мы будем отправлять все логи на машину loghost.mydomain.ru. Фокус с логами Давай теперь провернем еще один трюк: спрячем от взломщика все системные логи, чтобы он не только не смог их потереть, но и не узнал об их существовании. Для этого создадим "скрытую" директорию: mkdir /var/log/_hidden и добавим в /etc/_hidden/syslog.conf строчку: *.* /var/log/_hidden/all-logs. Теперь копии всех логов будут храниться в секретной директории. Вся прелесть в том, что взломщик будет до дыр протирать глаза, разглядывая дефолтный файл /etc/syslog.conf, но так и не найдет ничего подозрительного. Подобные фишки с подменой конфигов можно проделать и с другими демонами, например, inetd. Так что теперь все козыри (и логи) у тебя в руках, удачи ;). |