Сегодня расскажу, как можно протестировать свою ИТ-инфраструктуру или приложение на предмет устойчивости к DDoS-атакам на уровнях L4 и L7. Сразу скажу, что это нельзя назвать серьезным нагрузочным тестированием, это простой и бесплатный метод теста. У него две задачи:
Узнать, какой минимальной мощности достаточно, чтобы инфраструктура начала испытывать проблемы или легла вовсе. Это то, что тестировали мы.
Эту же методику можно использовать, чтобы оценить скорость реакции используемого сервиса защиты от DDoS-атак. Это не про то, чтобы попытаться заддосить с одной виртуальной машины мощные узлы фильтрации anti-ddos-сервисов. Скорее такой тест покажет, как быстро срабатывает защита и начинает блокировать зловредный трафик, для всех ли типов атак это происходит одинаково быстро и происходит ли вообще?
Про инструмент
Для тестирования будем использовать MHDDoS. Этот инструмент стал известен во время многочисленных DDoS-атак в 2022 году. Изначальная версия программы модифицировалась. Ее доделали под большую распределенную инфраструктуру и сделали возможным добавляться в качестве участника DDoS-атак user-friendly способом. Сделали своего рода DDoS как сервис. У коллег из UserGate была на Хабре хорошая статья по реверс-инжинирингу производного инструмента на базе MHDDoS. Но мы сегодня будем говорить про первоисточник и покажем, как его можно использовать на пользу.
Выбор пал на MHDDoS еще и потому, что он легко разворачивается на любой инфраструктуре (написан на Python) и имеет неплохую для open-source проекта документацию.
MHDDoS умеет атаковать на разных уровнях – L4, L7.
Есть стандартные (syn-flood, tcp-flood), атаки уровня приложений (post-, get-запросы, slow Ddos), амплификационные и заточенные под конкретные сервисы (Apache, например). Всего 56 типов атак на любой вкус.
Также заявлена возможность организовать атаку через прокси и использовать разные IP-адреса: авторы используют 96 источников с открытыми прокси, списки которых постоянно обновляются. Использование прокси позволяет увеличить ее мощность и усложнить ее блокировку. Но мы этого не делали.
Кроме того, с помощью MHDDoS можно запускать атаки, направленные на обход DDoS-сервисов.
Как это работает
Программа представляет собой скрипт на Python. Для любителей контейнеров есть Docker-образ. Загружаем скрипт с Github, устанавливаем окружение – и софт готов к использованию.
После запуска выбираете нужный тип атаки, например, L7 get-запросы.
Указываете, какой адрес атакуем. В случае с атакой L7 можно выбрать конкретный URL, куда пойдут запросы.
Выбираете мощность, количество потоков: сколько будет генерироваться запросов в секунду.
Устанавливаете длительность атаки.
Также для L7 программа просит выбрать тип прокси и файл со списком. Если укажем пустой файл, атака пойдет без прокси.
Если своих прокси нет, то программа предложит загрузить прокси из открытых источников.
Тестовый стенд
В качестве стенда мы возьмем две виртуальные машины (4 ядра и 8 Гб RAM) с Rocky Linux, между которыми растянута 10G-ная сеть. На машине, которая попадет под атаку, развернут OWASP Juice shop. Обычно он используется для изучения веб-уязвимостей, но сегодня попадет под DDoS-атаку :).
Файервольных правил, правил блокировки по количеству обращений и других механизмов защиты на атакуемой машине не настроено. В нашем случае сервис будет работать по HTTP, и нашей машине не придется тратить дополнительные ресурсы на обработку TLS-соединения.
Под капотом OWASP Juice Shop – легковесный веб-сервис с бэкэндом на Node JS.
На атакующей машине, соответственно, будет запускаться MHDDoS.
Собственно проверочная DDoS-атака
L4. Начнем тестирование с попытки забить полосу сгенерированными пакетами.
Выбираем атаку по UDP. Начнем со 100 потоков:
sudo python3 start.py UDP owasp.nubes.ru:80 100 60 yes
На пике получаем до 80 Мбит/сек, немного для UDP-трафика.
На этом этапе я попробовал запустить программу в однопоточном режиме:
sudo python3 start.py UDP owasp.nubes.ru:80 1 60 yes
С одного ядра, утилизированного в 100%, удалось получить порядка 200 Mbit/c в UDP-режиме, что уже гораздо серьезнее. 100-мегабитный канал можно забить. Нагрузка на RAM и CPU атакуемой машины практически не выросла.
В качестве второго сценария проведем L4 TCP-атаку.
Атаковать будем открытый сервис SSH:
sudo python3 start.py TCP owasp.nubes.ru:22 100 60 yes
В ходе атаки удалось утилизировать под 100% RAM и CPU атакуемой машины.
Процессоры атакующей машины утилизировались примерно наполовину.
При DDoS-атаке с одного IP-адреса количество TCP-коннектов возросло незначительно, при полноценной DDoS это значение может кратно увеличиться.
Получилось, что соотношение ресурсов, затраченных на атаку и утилизированных на атакуемом сервере, примерно 1:2.
Какие выводы можно сделать:
Минимальная необходимая мощность для вывода из строя сервера. Если сервис никак не защищен, то может хватить даже такой «школьной» атаки для загрузки его инфраструктуры.
Минимально необходимая мощность, чтобы забить канал. В моем случае я с одной машины забил 100Mbit-ную полосу.
L7. Для L7-атаки я решил попробовать использовать предлагаемые авторами прокси.
При первом запуске скрипта с пустым файлом прокси-серверов она опрашивает списки бесплатных прокси, заложенных разработчиками. Хоть скрипт и предупреждает, что проверка прокси может занять много времени, но в моем случае за 4 часа процесс так и не сдвинулся с места, а терпение закончилось. Поэтому атаковать с дефолтным списком прокси у меня так и не вышло.
Судя по телеграм-чату разработчиков, с такой проблемой столкнулся не только я. Ни в чате, ни на гитхабе ответов по решению этой задачи я так и не нашел. В целом, чат данного коммьюнити довольно интересен для исследования. Помимо обсуждения MHDDoS там множество предложений по продаже приватных прокси и более продвинутых DDoS-скриптов.
Позже я составил себе список бесплатных прокси из 200 хостов с ними и продолжил атаку.
Запускаем GET-запросы на наш OWASP Juice Shop.
Здесь нам обязательно надо выбрать тип прокси, файл со списком прокси-серверов и количество подключений к серверам.
sudo python3 start.py get http://owasp.nubes.ru/:80 0 100 proxy.txt 50 600 yes
Что имеем:
CPU на атакуемой машине полностью утилизировано, 8 GB RAM памяти тоже.
Нагрузка на CPU атакующей машины почти не возросла.
А что же с приложением?
На этапе планирования лабораторного стенда я думал, как буду замерять влияние DDoS-атаки на сервис и как измерить замедление в работе.
Но это не пригодилось: в любом режиме, независимо от количества потоков, OWASP Juice Shop падал через пару секунд после запуска атаки, выдавая ERR_CONNECTION_TIMED_OUT во вкладке браузера. Сервисы, развернутый в контейнере и классическим методом, выдавали одинаковые результаты.
Какие выводы можно сделать:
При прочих равных ресурсы, затраченные на DDoS-атаку, куда меньше тех, которые будут утилизированы на атакуемом сервере.
MHDDoS можно использовать для имитации DDoS-атак. Реализовывать DDoS возможно, но придется раздобыть прокси-серверы (в сообществах по DDoS приватные прокси для атак продают по цене от 20$).
Небольшой виртуальной машины или домашнего ПК в руках скрипт-киддиз достаточно, чтобы положить небольшой веб-сервис или забить 100 Мбит-ную интернет-полосу.
Не стоит пренебрегать защитой от DDoS, если даже такие бесплатные скрипты могут оказать негативное влияние на вашу инфраструктуру.
В качестве самой базовой меры включите хотя бы модули защиты от DDoS на сетевом оборудовании. Если их нет, сделайте правила блокировки по количеству подключений с одного IP. Это поможет в случае атаки с малого количества адресов. А если DDoS-атаки для вас не редкость, то лучше подключить специализированный anti-DDoS-сервис.