среда, 14 октября 2009 г.

Трюк который еще работает. Защита от DDoS на уровне javascript

Кто бы сомневался, что ботоводы - люди ленивые, иногда даже очень, очень. Вы думаете, что если у них много ботов, превосходный софт и предостаточно классных модулей к ботам то они будут это все сразу таки использовать, отнюдь - нет. Обычно, все начинается с простых GET запросов, даже не рандомных, на главную страницу и еще на несколько других тяжелых страниц, например - форум, фотогалерея и т.д. И только при неудаче, могут быть задействованы другие методы, рандомизация всего чего только можно, SYN flood, атака POST запросами, ICMP flood . . .

Предположим, что у нас есть сайт http://www.example.gov, его атакуют, по логам видно, что громадное количество GET запросов идет на:

http://www.example.gov/
http://www.example.gov/foto/
http://www.example.gov/forum/

В большинстве таких случаев можно обмануть ботов используя js-редирект. Старые и не профессионально написанные боты не содержат в себе js интерпретатора. Поэтому такой метод срабатывает лучше, чем можно было ожидать. Мы добьемся того, что боты не смогут нагружать базу данных, трафика будет в разы меньше.

Создаем index.html в корне сайта и в корне foto, forum каталогов.
прописываем туда наш простой js-редирект
И так с каждым разделом который атакуют GET запросом прямо в корень.Размер файла получится всего 90 байт, что гораздо лучше чем когда бот соприкасается к ~20кб странице и подтягивает ~10 SQL запросов. Легитимные пользователи у которых не отключен javascript в браузере будут перенаправлены на index.php. Единственное, что плохо, так это то, что поисковые-боты тоже не оборудованы js-интерпретаторами и точно так же как атакующие боты будут утопать в js редиректе.

Если рассмотреть конкретно этот случай защиты, то сразу просматривается уязвимость, защиту можно легко обойти если добавить боту функцию парсинга window.location.
И не нужен никакой js-интерпретатор.
Что бы избежать таких умных ботов с функцией парсера зашифруйте js-код, благо онлайн сервисов в интернете достаточно. 


Защита от DDoS с помощью утилиты tcpdump

tcpdump это мощнейшая утилита UNIX, позволяющая перехватывать и анализировать сетевой трафик, проходящий через сетевые интерфейсы. Об установке читайте в документации утилиты или на сайте разработчика, в FreeBSD она есть в портах, в Debian Linux в репозиториях.

Приведу пример как можно использовать tcpdump. Например, на сервере отключены логи, идет легкая ddos атака, происходит что-то не ладное, вы хотите быстро посмотреть масштабность или убедиться, что это DDoS-атака, а не DoS или может это вообще никак не связано с внешним миром? Давайте посмотрим:
tcpdump -v -i eth0 dst port 80
После выше набранной команды вы сможете наблюдать список подключений к 80-у порту, чем больше повторных подключений с одинаковых хостов тем вероятнее мы столкнулись с DoS или DDoS атакой. Как вы уже наверное догадались, изменив порт можно проверить есть ли атака на FTP, SSH или другие сервисы которые крутятся на сервере. Добавив ключ -n имена хостов преобразуются в IP адреса.

Глазами все не уследить, при атаке на веб-сервер вывод tcpdump-a сумасшедшей скоростью будет двигаться вдоль окна вывода терминала :) Поэтому, мы сначала запишем вывод tcpdump-a в файл. пакетов 200-300 хватит.
tcpdump -v -n -w attack.log dst port 80 -c 250
-v самый простой уровень логирования, без изысканности.
-n преобразуем имена хостов в IP адреса
-w записываем анализ трафика в файл
-c  количество захваченных пакетов

Приступим к анализу полученных данных через tcpdump, отпарсим лог следующей командой:
tcpdump -nr attack.log |awk '{print $3}' |grep -oE '[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}' |sort |uniq -c |sort -rn
Результат будет - 2 столбца, в первом количество подключений, во втором IP. Чем больше подключений для одного IP тем вероятнее что это бот.

Если список очень длинный можно ограничить его указав нужное количество выводимых строк
tcpdump -nr attack.log |awk '{print $3}' |grep -oE '[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}' |sort |uniq -c |sort -rn | head -20
Что бы получить только IP адреса, без первого столбца, нужно убрать ключ -c после uniq
Вывод парсинга можно перенаправить в файл, а затем простым bash-скриптом, заблокировать все IP со списка.

#!/bin/bash
BLOCKDB="ips.txt"
IPS=$(grep -Ev "^#" $BLOCKDB)
for i in $IPS
do
iptables -A INPUT -s $i -j DROP
Очень похожие трюки иногда проделывают с помощью утилиты netstat.

Пока это все, что я хотел написать о tcpdump. До скорых встреч!