"Спецвыпуск журнала «Хакер» #47, октябрь 2004 г." - читать интересную книгу автора (Хакер)Невидимость в *nix / Обзор stealth-механизмов бэкдоровПосле взлома системы чрезвычайно сложно оставить там незаметный черный ход. Опытные администраторы очень быстро обнаруживают все известные и неизвестные бэкдоры. О том, как перехитрить админа и скрыть присутствие лазейки в системе, и пойдет речь в этой статье. Давай подумаем, чем простейший бэкдор может выдать свое присутствие. Во-первых, он существует как файл. Администратор спосоен запросто обнаружить его с помощью элементарной утилиты ls и просто-напросто стереть, что нас ни в коей мере не устраивает. Во-вторых, если бэкдор запущен и работает, то он присутствует в системе как процесс. Соответственно, может быть обнаружен админом с помощью утилиты ps, вываливающей в консоль список процессов. В-третьих, черный ход «висит» на каком-то порту и ждет входящего соединения для того, чтобы открыть командный шелл взломщику, из-за чего может быть обнаружен массой различных способов, самым простым из которых является анализ результата работы утилиты netstat. Кажется, что проще бэкдор удалить и забыть об идее остаться незамеченным :). Не все так печально. Неспроста же изворотливый хакерский ум изобрел огромное количество способов сокрытия присутствия лазейки от любого, даже самого хитрого админа. Алгоритмы сокрытия бэкдора от утилит ps и ls практически идентичны, поэтому я разберу только случай маскировки процесса. Надеюсь, что с маскировкой файла у тебя трудностей не возникнет. Есть ощущение, что администраторы смотрят первым делом именно в вывод утилиты ps, когда у них возникает подозрение, что их системой пользуется тот, кто не имеет права этого делать. Наша задача сделать так, чтобы админ не обнаружил в списке процессов ничего подозрительного. Есть множество способов решить эту задачу, но мы рассмотрим самые популярные. Первый способ заключается в корректировке исходного кода утилиты, ответственной за вывод списка процессов. То есть мы должны будем найти сорцы ps, в них обнаружить функцию, которая выводит процессы на экран, и путем недолгих преобразований заставить забыть ее о нашем бэкдоре. Трудностей встретится целая куча: во-первых, придется рыться в чужих сорцах, а хуже, чем копаться в исходных кодах системных юниксовых утилит, ничего не придумаешь; во-вторых, реализация для каждой *nix-системы будет новая, ибо я сомневаюсь, что ps везде одинаковая. Также можно воспользоваться другим приемом, состоящим в маскировке созданного бэкдором процесса. Это самый простой в реализации способ. Потребуется написать программу, полностью заменяющую ps, которая выплевала бы всегда один и тот же текст. После взлома запомним список «постоянно висящих» процессов, запишем его, например, в файл, который и будем выводить всякий раз при запуске утилиты. Применение данного способа не требует от хакера глубоких познаний в программировании, хватит и школьного курса. Ведь в программу всего то и надо, что понапихать функций printf(). Жаль только, что любой нормальный админ в здравом уме и трезвой памяти заподозрит неладное сразу же после второго запуска ps. Ну и, наконец, самый интересный способ. Когда утилита ps пытается вывести все запущенные в данный момент в системе процессы, она обращается к ядру с некоторым системным запросом. Анализируя ответ ядра, она составляет список и выбрасывает его на экран. Способ маскировки бэкдора в данном случае будет заключаться в «обработке» этого самого системного ответа. Грубо говоря, требуется перехватить системный вызов и подменить его на фальшивый, в котором будут отсутствовать всяческие данные о нашем бэкдоре. Осуществить это можно, написав Loadable Kernel Module (LKM), модуль, подгружаемый к ядру системы. Он подменит запись в таблице системных вызовов, в результате чего все запросы будут передаваться не стандартной функции, выдающей список процессов, а нашей хитрой процедурке. Похожий модуль был написан stan'ом из команды unl0ck team, но, к сожалению, он не захотел делиться с народом полноценной программой, поэтому написал некий PoC, который заставляет программу ps и ей подобные выводить сообщение о том, что в системе процессов нет как таковых. Немного подкорректировав код модуля (ты найдешь его на CD, прилагающемся к журналу) и добавив в него функцию поиска и сокрытия нужного нам процесса, можно добиться самой качественной маскировки своего бэкдора. Достоинства этого способа очевидны. Администратор не сможет обнаружить никаких изменений в размере файла утилиты ps, как в случае с ее подменой. А если вдруг он воспользуется какой-нибудь сторонней программой для слежения за запущенными процессами, то и ее вызов не выдаст нашего бэкдора, ибо ядро одно, а работают подобные программки по одному и тому же принципу. Здорово! Впрочем, у этого метода есть и недостатки, главным образом, сложность реализации. Ведь, чтобы написать такой LKM или подкорректировать уже имеющийся на врезке, нужно нехило разбираться в программировании модулей, а этим может похвастаться далеко не каждый программер. Думаю, с сокрытием процесса бэкдора, а также файла, маскировка которого реализуется по аналогии, мы разобрались, и можно приступить к самой ответственной части материала. Каждому юниксоиду известно, что для просмотра списка открытых соединений в системе применяется утилита netstat. Если будет использован обычный бэкдор, который открывает шелл на заданном TCP-порту, первый же запуск этой программки выдаст взломщика с головой. Как же укрыться от netstat? Аналогично ситуации с ps, способов очень много. Один из них, как это ни парадоксально, очень популярный, заключается в такой корректировке самой утилиты, которая бы не позволяла ей показывать наше соединение. Для реализации этого способа потребуется отыскать сорцы netstat в сети и как следует их перелопатить. По-моему, такое и в кошмарном сне не приснится. Другой способ – написать LKM, который бы перехватывал системные вызовы утилиты netstat. Это вообще самый лучший подход к редактированию вывода любых системных утилит, будь то ps или netstat. Он немного сложен в реализации, но, если знать, куда копать – какие системные вызовы в каких случаях перехватывать, то справиться можно. Допустим, нам удалось скрыть бэкдор из списка открытых соединений. А что, если администратор проверяет свою систему не локально, а, например, удаленно с помощью различных программ вроде nmap? Тогда при сканировании администратор заметит, что в системе открыт «левый» порт, а netstat его не показывает. Админ сразу же просечет фишку, и больше мы на его машину не попадем. Именно для таких случаев хакеры придумали еще кое-что для сокрытия своего присутствия в системе. При написании бэкдора следует использовать не Грамотный администратор не всегда ограничивается стандартными средствами при поиске бэкдора в своей системе. Иногда он прибегает к поиску злоумышленника с помощью снифера или IDS, подобной Снорту. А от зоркого глаза (или чуткого носа? :)) «нюхача» не скроется ни один даже самый навороченный бэкдор. Как же уберечься от надоедливого админа или его кошмарной IDS? Тут поможет только одно – полное шифрование трафика, которое уберет заметный plain text команд из логов снифера. Хакеры используют для этого самые разные криптоалгоритмы: и IDEA, и xTEA, и Blowfish, и Twofish. Но, даже шифруясь, не стоит забывать, что лишний гигабайт трафика, генерируемый к тому же каким-нибудь RAW-сокетом, заметит даже слепой админ. При использовании чужих мощностей надо знать меру :). В этой статье я описал лишь самые популярные подходы к маскировке. Время не стоит на месте, постоянно изобретаются все новые и новые способы сокрытия бэкдоров. Старайся не отставать от прогресса, ведь не просто так говорят: «Кто остановился, тот умер!» Linux Kernel Module #include lt;linux/module.hgt; #include lt;linux/kernel.hgt; #include lt;sys/syscall.hgt; /* linux ps fake utility. * * if fake ps doesn't work, try below SYS_CALLS * * 1. SYS_rt_sigaction * 2. SYS_rt_sigprocmask * 3. SYS_clone * * the main hook function is fakepid(); this function try to * hook SYS_call = SYS_waitpid, then programm print some inte * resting message to the screen :) * * (c) by stan [unl0ck team] 2004 */ extern void *sys_call_table[]; int (*origpid)(const char *path); int fakepid(const char *path) { printk(«No proccess found!»); return 0; } int init_module(void) { origpid = sys_call_table[SYS_waitpid]; sys_call_table[SYS_waitpid] = fakepid; printk(«Module successfully loaded!»); return(0); } void cleanup_module(void) { sys_call_table[SYS_waitpid] = origpid; printk(«Module successfully unloaded!»); } Случается так, что опытный администратор ухитряется выловить stealth-бэкдор, даже если в нем применяются все перечисленные здесь механизмы. Продвинутые админы напридумывали кучу самых разных приемов выловить гада. Они используют сниферы и анализируют трафик на предмет чего-то подозрительного, устанавливают жесткую политику брандмауэров. Со всем этим очень сложно бороться стандартными методами. В такой сложной ситуации есть отличный способ остаться незамеченным. Можно немного подкорректировать какой-нибудь сервисный демон. Например, написать патч к ssh, позволяющий беспрепятственно проникнуть в систему без аутентификации и прочих штучек. Ничего особенно трудного здесь нет, нужно лишь немного разбираться в кодинге. Есть еще более простой способ – проход в систему посредством доверенных хостов. Многие сетевые демоны, такие, как sshd, rlogin, rshd, при соединении с кем-либо обращаются к файлам ~/.rhost, /.rhost (uid=0 auth), /etc/host.equiv, ~/.shosts, проверяя, нет ли там адреса соединяющегося с ними пользователя, и если есть, то документы у него не спросят. То есть, если нам вписать в вышеперечисленные файлы некий хост, то он будет пропущен на сервер без аутентификации. А если в этом файле будет пара «+ +», то на сервер сможет войти вообще любой хост без предварительной аутентификации. В этом случае может очень пригодиться crontab для того, чтобы поставить точное время, когда нужно создавать/удалять файл доверенных хостов – мы же не хотим, чтобы администратор нас засек. При этом следует помнить, что перед уходом с сервера нужно почистить логи. Но не полностью удалять, а аккуратно подрезать записи, оставленные системой только о собственных грязных делишках :). Не всегда есть возможность и желание писать бэкдор самому. Я приготовил коротенький обзор полезных бэкдоров/руткитов, доступных в сети: Bdoor.c – бэкдор, маскирующийся под HTTP-демон. Он не использует никаких stealth-технологий. Применять его можно только в расчете на невнимательность администратора (явление, надо признать, очень частое). SYS_getuid был бы просто отличным руткитом, если бы не так просто ловился в системе. Для его обнаружения достаточно сделать копию таблицы системных вызовов после установки системы (до того как система затроянена), а потом время от времени сверять указатели, текущую таблицу с копией, любые расхождения будут означать присутствие бэкдора. Superkit – замечательный многофункциональный руткит. Умеет прятать файлы, процессы, соединения в netstat. Имеет функцию защиты паролем. Умеет открывать порт и запускать на нем удаленный шелл. И самое приятное – он не может быть обнаружен с помощью сравнения таблиц системных вызовов. Linuxrootkit5 – это довольно старый, но не потерявший своей актуальности руткит. Помимо стандартного набора функций lkm-руткита, он умеет прятать cron-записи, что бывает очень полезно, когда стараешься обхитрить админа любыми способами. kbdv2.c – Linux loadable kernel module backdoor. Классический пример бэкдора, подгружаемого к ядру системы. Перехватывает системные вызовы (SYS_stat, SYS_getuid). Интересен бэкдор не столько своими функциями, сколько хорошо комментированным исходным кодом. Его изучение может быть очень полезно при написании собственной программы подобного рода. Neth – детище Forb’а. Отличный бэкдор! Написанный с использованием «сырых» сокетов, он не открывает TCP-портов, за счет чего не палится ни netstat’ом, ни удаленным сканером. Практически все перечисленные мной программки можно скачать с сайта www.packetstormsecurity.nl. Бэкдор – черный ход в систему. Массу полезной информации и программ ты можешь найти на www.packetstormsecurity.nl. Умный админ может регулярно считать MD5-хэши от всех файлов в системе. Он без труда может заметить изменения в системных утилитах. Утилита cron поможет обхитрить администратора. От удаленного сканирования может спасти только использование RAW-сокетов. Не стоит забывать, что любой, даже самый хороший бэкдор может выдать свое присутствие огромным трафиком. Перехват системных вызовов – самый уважаемый в хакерских кругах способ сокрытия бэкдора от утилит операционной системы. |
||
|