Принципы проектирования очень больших ботнетов
Для ведения войны мне необходимы три вещи: во-первых — деньги, во-вторых — деньги и в третьих — деньги. (с) Наполеон Бонапарт
Большие ботнеты - закрытая тема, на которую не то что в паблике не разговаривают, а даже в сверх-секретном-привате мало интересных обсуждений. И одна с причин этому - ограниченное количество таких ботнетов. Ведь мы говорим о размере в сотнях тысяч зараженных компов. Но, несмотря на закрытость этой информации, я тебе расскажу абсолютно все самое интересное.
Два года назад моя "аналитическая" группа получила заказ на разработку идеальной архитектуры большого ботнетов. Месяц ушло на изучение существующих решений их анализ, и придумывания своих вариантов. То, что получилось, было реализовано людьми и сейчас отлично работает ;). С заказчиком был договор, что 2 года мы не будем распространять данную информацию, но сейчас время вышло и ты будешь первый кто сможет это узнать, и может быть реализовать данную архитектуру для своего ботнета.
В статье мы рассмотрим:
- условия существования больших ботнетов;
- удержания контроля;
- генерация доменов;
- масштабируемость;
- возможность разделения;
- подача команд, их защита;
- возврат результатов.
Не простая жизнь больших ботнетов
Если у тебя ботнет на тысячу иль 10 тысяч компов, то с ним много проблем, но все они кажутся ничтожными по сравнению с проблемами, когда размер перевалил за цифру в сто тысяч. Ведь на тебя и ботнет откроют настоящая охоту антивирусные компании, правоохранительные органы и обычные гении, которым от нефиг делать захочется посмотреть, что же внутри у твоего бота. Да и "коллеги" не оставят в покое, а всеми средствами будут пытаться угнать ботнет. Тебя конечно ждет слава, и может даже покажут по ТВ ;), но эта слава может полностью убить твой бизнес, если архитектура ботнета плохоя.
Это война, в ней можно победить лишь использовав последние достижение в науке. Чтобы убить твой ботнет "враги" будут полностью анализировать его, смотреть что и как он делает, да и еще дизассемблировать код. И никакие антиотладочные приемы, многократная полиморфная криптовка и прочее не поможет закрыть внутренности бота от них.
С этой первой проблемой можно бороться соблюдая первое правило ботнетов: "нужно разрабатывать ботнет считая что вся информация о нем будет полностью открыта". Вторая проблема возникает с масштабом ботнета, ведь огромное количество ботов не выдержит ни один сервак, а поставить кластер с распределителями нагрузки у тебя не получится, потому что это слишком сложно и долго. А когда даже все будет готово, то придут федералы (я так буду называть ФБР, ФСБ, СБУ и прочих) и быстренько все конфискуют. С этого рождается второе правило: "ботнет должен управляться с обычных серверов".
Теперь можем приступить к рассмотрению архитектуры, что сможет соответствовать этим правилам.
Командный центр
Способ общения с ботами это позвоночник ботнета. Раньше очень популярный было передача команд через IRC, где боты заходили в заранее определенные комнаты, и ждали, что кто-то передаст им команду. Ну этот метод только археологи сейчас используют, и о его множествах проблем даже не хочется говорить. Сейчас чаще всего используется или схему p2p или web.
p2p - достаточно интересная схема, которая имеет право на жизнь при больших ботнетах. В ней преимущество то, что нагрузка по передаче команд лежит на самих ботах, но минусов в ней тоже хватает:
- сложность архитектуры;
- нестабильность сети;
- паливность открытия портов;
- сложность контроля;
- сложность отдачи результатов от ботов;
- и многое прочее...
Управления ботнетом по web'у сейчас самый идеальный вариант. К примеру, возьмем Zeus, у него в конфиге прописываем основной домен, где админка, и дополнительный домен (если первый сервак накроется). Но если завтра ботов будет много, то они легко положат сервак, а если сервак и выдержит, то послезавтра придут федералы и прикроют как основной так и дополнительный домен, после чего уже восстановить управления над ботнетом не удастся. Как видим эта схема абсолютно не подходит для больших ботнетов.
Невозможность — слово из словаря глупцов.
(с) Наполеон Бонапарт
Генератор доменов
На как в известном фильме легким движением руки штаны превращаются в шорты, так и мы можем бесполезную схему превратить в идеальную. И ключевая идея в динамической генерации доменов, через которые бот будет общаться. Генерировать доменов будем используя генератор псевдослучайных чисел (ГПСЧ), если ты не знаком с ним, то посмотри врезку - там я коротко описал. Но для нас важна одна фишка, если на вход генератора дать число 1234, то генератор может вернуть: 6452, 12, 761 и т.д. И сколько бы раз и на каком компьютере это не повторяли, всегда последовательность будет одинакова.
Исходя из этого мы можем написать функцию, что будет использовать генератор псевдослучайных числе, и если передать какое-то число на генератор, то он сможет сгенерировать случайную бесконечную последовательность доменов. Нам лишь нужно для синхронизации всем ботам передать одинаковое начальное число для начала генерации.
Теперь принцип работы бота следующий:
- генерирует псевдослучайный домен;
- проверяет, есть ли на главной странице домена какой-то определенный текст - маркер;
- если маркера нет, то возвращаемся к первому пункту;
- если маркер есть, то получаем команду для исполнения.
.com
.org
.ho.ua
Где .ho.ua обычный бесплатный хостинг, и если он попадет в последовательность, то нам даже не нужно будет покупать домен, а бесплатно себе зарегаем поддомен и этого будет достаточно.
Бот, после проверки маркера, должен запрашивать определенный текстовый файлик, к примеру, temp123.txt, и оттуда брать команду для исполнения.
Если рассматривать задачу управления, то у нас тоже есть такой же генератор как и у бота, и можем получить первый домен. Дальше пробуем его зарегать, если не получилось, то забиваем на него. Берем второй домен с последовательности, если получилось его зарегать, то вставляем маркер на главную страничку, и создаем файлик temp123.txt с командой. Если когда то потеряем доступ к домену (или абуза будет, или федералы отберут), то генерируем третий домен и уже туда помещаем команду. Тоесть в такой схеме перекрыть доступ к ботам невозможно. Ведь если нам закроют миллион доменов с последовательности, то мы команду поместим на миллион первом, а боты все равно найдут этот домен.
Масштабируемость
Поскольку для управления используем обычные серваки, то быстро столкнемся с проблемами нагрузки, и сервак начнет не выдерживать и падать. Поэтому был разработан такой вариант - разделения ботнета на подсети. Разделения делается командами, тоесть бот стучит на сервак и читает оттуда приблизительно такую команду:
разделиться: 3001-3004
Что буквально значит, выбрать случайным образом (в этом случае действительно нужно случайное число) число от значения 3001 до 3004 и использовать его для генерации последовательности доменов. Этим мы разделяем ботнет на 4 части и у каждой части теперь будет своя последовательность доменов и они будут стучаться на разные серваки за командами. А нам же лишь остается зарегать 4 новых доменов (по одному для каждой последовательности) и помещать команды управления на них.
Так мы сможем делить нашу систему на сколько хочем независимых участков. И уже каждому участку задавать команду. Также можем дать команду слиться ботам:
разделиться: 3001
Как видим получили отличную масштабируемость, да к тому же, как побочный продукт, можем давать разные команды разным участкам, что иногда полезно.
Защита команд
Недавно в инете проскакивала новость, что какие-то ученые получили доступ к ботнету на несколько дней и что-то там анализировали. Но нам это вообще не нужно. А сейчас это делается очень просто, ведь федералы могут проанализировав бота узнать команды и узнать домены, где боты ищут команды, а дальше передать любую команду, например, "самоуничтожиться".
Как вариант защиты, мы можем шифровать AES-ом, а потом переводить в BASE64. С одной стороны шифрование мощное, но если бота могут дизассемблировать и достать пароль :(.
И выходом есть технология, которую американские власти очень боялись. Даже одно время запретили прогу на несколько строчек написанную на Perl'е. А люди потом для борьбы с этим прогу печатали на футболках. И эта история о RSA.
С помощью RSA можно как шифровать сообщения так и подписывать информацию, тоесть гарантировать то, что именно мы написали подписанную информацию. Этим и воспользуемся. Сгенерируем два ключа паблик-ключ и приват-ключ, и в каждый бот запишем паблик-ключ. А приват-ключ будем хранить у себя.
Файл с командами теперь должен быть таким:
1. случайная_последовательность
2. tutamc.com
3. 00:01 08.07.2009
4. 23:59 09.07.2009
5. команда 1
6. команда ...
7. хеш_сгенерированный_приватным_ключем
В первой строчке случайная последовательность, что необходим для защиты от расшифровки приватного ключа. Во второй строчке размещается случайно сгенерированный домен на котором находится команда - это защищает от несанкционированного нами копирования файла на другие участки ботнета (помним с масштабируемости, что ботнет можно разделять по доменным последовательностям). В третьей и четвертой строчке время с какого и по какое команда актуальна. Дальше идет список команд. Последняя строчка сгенерированная приватным ключом - подпись, которая гарантирует, что команда пришла именно от хозяина ботнета.
Бот когда считывает команду, то своим публичным ключом может проверить - соответствует ли текст подписи, если да - все окей, если нет, то значить что команду нельзя исполнять.
Этот способ позволяет полностью защитить ботнет от "врагов", ведь сейчас не существует способа расшифровки RSA при ключе в 2048 бит.
Полностью держать команды в открытом виде тоже не всегда интересно, хотя никто никак повлиять не может, но от любознательных еще можно защититься сверху зашифровав файл с помощью какого-то симметрического ключа, типа AES.
Также при разработке бота следует реализовать команду по смене публичного ключа в бота. Это нам даст способ передачи части ботнета в другие руки, например при продаже. Мы можем попросить у покупателя сгенерировать публичный ключ и дать нам (а приватный ключ покупатель нам не должен давать, что гарантирует то, что мы не заберем когда-то ботнет назад). Дальше нужно дать ботам, к примеру, такую команду:
взять_новый_публичный_ключ: "публичный ключ"
Возврат результатов
Некоторым ботнетам не нужно отсылать обратно информацию, но а для некоторых это обязательное условие. И опять же возникает вопрос о безопасной передаче. Ведь если бот отдает список паролей от палки, то не очень приятно если федералы захватив доступ к серверу потом заблокируют аки, что боты старательно собирали. Для решения проблемы опять же возьмем любимый RSA. Ведь он позволяет с помощью публичного ключа, что есть в каждом боте зашифровать сообщения, и его расшифровать сможем лишь мы с нашим секретным приватным ключом.
Для записи же информации на сервер я советую использовать POST-метод. Тоесть заранее определяем имя скрипта, что будет принимать данные, к примеру tttt123.php. А бот после получения команды отсылает шифрованные результаты на домен откуда получена команда, на файл tttt123.php, который лишь записывает файл на диск. Дальше мы его забираем к себе на комп и уже там расшифровываем приватным ключом и потом анализируем.
Если не можешь победить честно, просто победи.
(с) Улисс Симпсон Грант
Админка
Вот мы с тобою и рассмотрели архитектуру, что кажется идеальной, по крайней мере я не вижу в ней уязвимых моментов. Хотя есть минус, система сложновата в управлении, и для решения этой задачи мною была разработана удобная админка на Python'e, что автоматизирует рутину управления. К сожалению ее описание уже выходит за рамки статьи, но если тебе все же интересно узнать о ее написании - напиши Forb'у или мне, и мы в отдельной статье ее рассмотрим.
from my Совесть (ага, немного осталось, все никак не избавлюсь)
Я, как лейтенант милиции, должен тебе напомнить, что вся информация лишь для ознакомления.
Как видишь даже математика иногда (или всегда) бывает полезна, и то время что ты потратил или еще потратишь на ее изучение никогда не будет лишним. Если будут вопросы, или не очень понятные места в статье - обращайся. Удачи в захвате мира ;). И если тебе это удастся - не забудь меня и пришли открытку на день милиции - 10 ноября.
