Мистецтво зомбування Азбука створення ботнетів

Зміст статті

Сучасні бот-мережі за своєю чисельністю давно переступили мільйонну планку. Їхні масштаби дозволяють бот-майстрам «розпаралелити» фінансові потоки від послуг. Нинішні підходи до проектування ботнету дозволяють використовувати його як для здійснення DDoS-атак, що вже стали класикою в наш час, так і для роботи на рівні окремо взятих хостів.

Зацікавитись дітищем можуть як конкуренти, так і правоохоронні органи. Усі можливі ризики мають бути також виявлені та усунені на етапі проектування. Рік тому в нашому журналі концепцію ідеального ботнету детально описав Роман Хоменко у статті «Вічний ботнет». У ній він виклав принципи створення роботу, організацію отримання команд від командного центру, а також вніс деякі постулати проектування бот-мережі. Раджу взяти його матеріал за основу. У свою чергу, наслідуючи теоретичні аспекти побудови «ідеальної армії», ми розглянемо практичну сторону створення бота.

Архітектура - наше все

Існує безліч способів керування зараженими хостами та передача команд кожній машині. Все залежить від конкретних уподобань бот-майстра. Залежно від типу протоколу, що використовується, командним центром може виступати:

Не треба турбуватися про своєчасне отримання команди конкретним роботом. Факти отримання, виконання, успішного/неуспішного завершення завдання легко фіксуються, що дозволяє проводити детальну статистику. Однак централізована топологія залишається актуальною лише для невеликих бот-мереж з таких причин:

  • Погана масштабованість (зі зростанням числа заражених хостів зростає навантаження на командний центр і збільшується ймовірність здійсненняатаки типу "відмова в обслуговуванні" на сервер, що передає завдання);
  • Централізоване управління (висока можливість ізолювання командного центру, що негайно «паралізує» весь ботнет).

Децетралізована топологія повністю позбавлена ​​перелічених вище недоліків і в силу особливостей своєї архітектури забезпечує велику «живучість» бот-мережі. Але, як завжди, в бочку меду обов'язково кимось вилита солідна ложка дьогтю, і в нашому випадку не одна:

  1. Peer-to-peer схема передбачає повідомлення кожного робота про існування інших заражених машин. Ця процедура є досить «палевною», тому що необхідно зберігати на кожній зараженій робочій станції величезний (ми розглядаємо великі ботнети) файл зі списком IP всіх роботів мережі та в реальному часі його оновлювати, якщо потрібна доставка команд кожній «бойовій одиниці»;
  2. Оновлення списку та отримання команди вимагають додатково відкритих портів на зараженій машині, що збільшує ймовірність виявлення ботнета;
  3. Значний час витрачається на передачу завдання від хоста до хоста (P2P) та, відповідно, зростає загальний час його виконання;
  4. Складність ведення статистичних даних (скільки роботів отримали/виконали завдання).

Найчастіше велика кількість недоліків і складність реалізації P2P-ботнетів є вирішальними чинниками на користь вибору централізованої топології. Ми також не винаходитимемо велосипед, а скористаємося світовими практиками.

Примхливий командний центр, який постійно перебуває в умові нестійкої рівноваги, прагнучи впасти за найменшого зростання нашої «армії», так і намагається віддатися в руки правоохоронних органів, які ось-ось прикриють головний домен. Хай прикривають хакер його змінить.

Псевдовипадкові імена

Генератор псевдовипадкових чисел має одну особливість, яка є ключовою для бот-майстра - отримуючи на вхід параметр у вигляді фіксованого значення, ГПЛ генерує випадкову послідовність, яка буде однакова на різних робочих станціях за умови отримання їх генераторами цього параметра. Щоб тобі не довелося довго шукати сенс у використанні ГПЛ, розглянемо таку функцію:

Функція генерації псевдовипадкової послідовності

int generator (int seed) srand (seed); /* виведення двадцяти перших елементів послідовності*/ for (x = 1; x

Базовими функціями, що відповідають за ініціалізацію та генерацію псевдовипадкової послідовності, є давно знайомі нам srand() та rand(). На основі змінної seed функція srand() ініціалізує безліч чисел, на якому, у свою чергу, працюватиме функція генерації rand().

Результат роботи функції generator() при значенні seed=123:

Таким чином, seed є тим самим параметром, на основі якого генеруватиметься послідовність доменів. Легким рухом руки і невеликим ворушінням звивин генератор псевдовипадкової числової послідовності перетворюється на генератор псевдовипадкової послідовності доменних імен.

Маючи у своєму функціоналі генератор доменного імені, у разі недоступності командного центру на основному домені бот генерує новий та зв'язується з ним. У свою чергу, бот-майстер також має в наявності аналогічний генератор (з потрібним вхідним параметром seed), що дозволяє заздалегідь зареєструвати нове доменне ім'я для своєї «армії».

Таким чином, ми позбулися одного з основних недоліків централізованої топології — можливості знищення командного центру. Однакзалишається загроза отримання контролю над доменом та несанкціонованої передачі команд ботам. Ця проблема вирішується спеціально спроектованою адмінською частиною (також відомою як «адміністративна панель»).

Ботнет та .NET

Один із методів захисту від несанкціонованої передачі завдань роботам полягає у використанні шифрування командного файлу на стороні сервера. Клієнт, яким виступає заражена машина, має у своєму розпорядженні ключ для розшифрування цього файлу. Ідея хороша, але ми підемо іншим шляхом, скориставшись принадами сучасних технологій.

  • Аутентифікація - безпосередньо розпізнавання клієнта, що запитує ресурс;
  • Авторизація - визначення, чи має автентифікований клієнт необхідні права на запитуваний ним ресурс.

Для встановлення процесу аутентифікації у конфігураційному файлі веб-сервісу Config.Web необхідно внести відповідні зміни:

Таким чином, ми встановлюємо процес аутентифікації на основі Cookies-файлів. Далі для аутентифікації клієнта необхідно прийняти від нього дані (UserLogin та UserPassword), звірити їх з необхідними та, у разі успіху, передати йому cookies-файли, які знадобляться клієнту для отримання доступу до захищеної частини сайту, де зберігається командний файл:

«Пиляти» адміністративну частину ботнету можна не менш тривалий час, ніж самого бота, тим більше, якщо в розпорядженні є цікаві технологи захисту веб-додатків ASP.NET, тому ми не намагатимемося осягнути неосяжне, а перейдемо до ключової частини бота.

Бот у розрізі

Будь-який сучасний ботнет має на увазі розширення свого функціоналу. Навіщо? Ну, наприклад, якщо у бот-майстра виникло бажання перекваліфікувати свою армію зомбі до мережірозподілених обчислень, що буде моделюванням наслідків ядерних вибухів. Плагінна архітектура дозволяє «розв'язати» руки адміністратору мережі та нарощувати чи оновлювати функціонал у міру потреби. Враховуючи цей факт, складемо алгоритм дій нашого бота:

  1. одержання команди від сервера;
  2. обробка команди, тобто її класифікація на «відому» чи «невідому»;
  3. обробка відповідним чином параметрів команди, залежно від її типу;
  4. виконання команди.

Отримання команд полягає у завантаженні текстового файлу із сервера (command.txt). Реалізацію скачування файлу перебирає функція HTTPDownload(char *FileUrl, char *FileName). Ця функція також використовується і для завантаження необхідних .dll для ботнета. Я вирішив не займатися рутиною, працюючи із сокетами, а скористатися стандартною бібліотекою, яка є у Windows: wininet.dll.

Дана DLL є API для доступу до загальних протоколів інтернету, включаючи FTP, HTTP та Gopher. Це високорівневий API, що дозволяє, на відміну від WinSock або TCP/IP, не дбати про деталі реалізації відповідних інтернет-протоколів. Для отримання команд бот повинен періодично з'єднуватися із сервером, завантажувати командний файл та відповідним способом його обробляти. Під обробкою ми маємо на увазі дію, в результаті якого бот отримує два рядки: назву команди та рядок, що містить параметри до неї, перелічені через символ пропуску. Командний файл має таку структуру:

Структура командного файлу

[параметр(1)] [параметр(2)] … [параметр(i)] [параметр(1)] [параметр(2)] … [параметр(j)] … [параметр(1)] [параметр(2)] … [параметр(n)]

де i, j, k змінюються вінтервалі (1; нескінченність).

Дії роботи такі:

  1. виділення k-ого рядка;
  2. передача виділеного рядка до функції, яка реалізує підключення бібліотеки, необхідної для виконання команди (функція PlugLibrary());
  3. PlugLibrary() відповідним чином інтерпретує рядок і виконує необхідну дію, що залежить від типу команди. Парсинг command.txt реалізує функцію Parse(char *FileName).

У разі необхідності підключення завантаженої dll'ки з метою розширення функціоналу, функція PlugLibrary виконує наступні інструкції щодо заздалегідь описаного інтерфейсу підключення (він також має бути оформлений у самій dll):

Функція Load, що експортується бібліотекою, містить необхідні інструкції, що забезпечують розширення функціоналу основної програми-бота.

І це лише початок…

У статті ми трохи підглянули за процесом приготування ботнету за правильним рецептом. Наша увага торкнулася більшості аспектів мистецтва зомбування: проаналізовано основні архітектури бот-мереж, здійснено реалізацію найбільш актуальної топології з усуненням властивих їй недоліків, розглянуто досить перспективну область використання вебсервісів як адміністративну панель зі своєю захищеною зоною, написано плагінний бот, який у міру бажання може мутувати до невпізнання. І це тільки початок, адже скільки нюансів залишилося за кадром: приховування файлу в системі, що виконується, поділ ботнета на підмережі і тому подібні завдання, які тобі ще належить вирішити. Я лише задав тобі напрямок руху, природно, виключно в ознайомлювальних цілях.