Популярность веб-приложений (к которым относятся сайты, интернет-магазины, личные кабинеты, API и т.д.), большой стек применяемых технологий, дефицит опытных разработчиков, а доступность различного инструментария и знаний в области тестирования на проникновения приводит к ожидаемым последствиям — компрометации веб-приложения. Давайте попробуем повысить его защищенность.

Серверное окружение

Как обстоят дела с периметром? Доступны только порты для работы с HTTP? Или FTP/SSH etc. для удобства работы с контентом и обслуживанием сервера из любой точки мира? Имейте ввиду, что логин/пароль для SSH/FTP можно подобрать, а Fail2ban может и не сработать (или, наоборот, используя особенность работы Fail2ban можно заблокировать любой другой IP, а не только свой). Каждый доступный для атакующего сервис повышает риск компрометации. Не стоит забывать своевременно устанавливать обновления и периодически выполнять проверку сканерами уязвимостей.

Веб-приложение

Лимит обращений и ядро

Прежде, чем анализировать запросы, рекомендуется установить лимиты обращений. Это можно сделать, например, с помощью ngx_http_limit_req_module в Nginx. Установите оптимальное для вашего сервера количество запросов, чтобы снизить нагрузку в случае DoS-атаки. Кроме того, можно произвести тонкую настройку ядра, увеличив количество обрабатываемых соединений, времени таймаута при установке соединения, управлять взаимодействием со swap и т.д. Подробнее в этой статье.

Nginx: ограничиваем количество обращений к веб-серверу

...
limit_req_zone $req_limits zone=default_req_limits:10m rate=25r/s;
...

location / {
 ...
 limit_req       zone=default_req_limits;
 ...
}

т.е. устанавливаем лимит обращений для каждого IP-адреса: не более 25 запросов в секунду. Можно управлять не только количеством запросов, но и их всплеском (burst) и т.д.

Нежелательный User-agent

Отсечь часть нежелательного трафика можно простым добавлением списка блокируемых user-agent’ов в nginx.conf:

Блокируем нежелательные UA средствами Nginx

map $http_user_agent $blacklist_ua {
 ~*nmap                  1;
 ~*nikto		 1;
 ~*wikto                 1;
 ~*sqlmap                1;
 ~*bsqlbf                1;
 ~*acunetix              1;
 ~*havij                 1;
 ~*appscan               1;
 ~*wpscan                1;
 ~*ApacheBench           1;
 ~*DirBuster             1;
 ~*w3af                  1;
 ~*Arachni               1;
 ~*XSpider               1;
 ~*Hydra                 1;
 ~*Evasions              1;
 ~*OpenVas               1;
}

Веб-приложение

Чаще всего мы сталкиваемся с 2 типами атак: нецеленаправленная эксплуатация популярной уязвимости (к примеру, попытка эксплуатации уязвимости для Drupal на WordPress) и попытки подбора пароля (реже — других параметров).

Атаки методом перебора (brute-force)

Распространенный пример — атакующий пытается подобрать пароль к учетной записи. Помимо риска компрометации, такие атаки перегружают веб-приложение (интерпретатор, БД), ограничивая взаимодействие с ним легитимным пользователям.

Блокировать атаки методом перебора не всегда просто, особенно если невозможно использовать капчу или атака распределенная (атакующий может использовать прокси-сервера, в том числе бесплатные, которых тысячи), а другие параметры запроса (например, User-agent) — различаются. В самой масштабной распределенной атаке, с которой нам приходилось сталкиваться, было задействовано около 65.000 адресов.

Выявляем атакующих по схожести их запросов:

  • Сбор поступающих запросов.
  • Извлечение необходимых для принятия решения данных.
  • Фильтрация с исключением нецелевых URI для повышения точности
    определения атаки.
  • Расчет взаимных расстояний между запросами с использованием расстояния
    Левенштейна и нечеткой логики.
  • Выбор по мере близости в рамках определенного временного окна запросов с
    одного IP на конкретный URI; или (для выявления распределенных атак) выбор всех
    запросов на конкретный URI, независимо от IP.
  • Блокирование источника(ов) атаки по IP-адресу(ам) при превышении пороговых
    значений.

Так это выглядит на практике:

Атаки методом перебора, помимо угрозы компрометации данных (логин/пароль, бонусные баллы, номера телефонов и т.д.), создают повышенную нагрузку на сервер, ограничивая доступ легитимных пользователей. Как правило, такие атаки не требуют больших мощностей, а для распределенной атаки злоумышленник может использовать публичные прокси-серверы (в том числе бесплатные).

Нецелевые атаки

Популярный пример такой атаки — злоумышленник производит массовое сканирование сайтов с помощью автоматического инструментария, развивая атаку на те сайты, где была обнаружена уязвимость. Использование WAF и системы блокирования на определенное время атакующего (бан) позволит значительно снизить риск обнаружения уязвимостей. Можно использовать связку ModSecurity/Naxsi + Fail2ban, потратить время на настройку и адаптацию, а можно использовать Nemesida WAF Free (бесплатная версия Nemesida WAF), которая помимо качественной сигнатурной базы имеет встроенный механизм блокирования источника на определенный промежуток времени. Кроме этого, заблокированные запросы отображаются в личном кабинете, в котором можно увидеть как состав сигнатуры, которая привела к блокированию запроса, так и получить готовое правило исключения (WL), если блокирование запроса произошло по ошибке:

Целевые атаки

Как правило, сложная атака, сопровождающаяся предварительным анализом веб-приложения. При такой атаке изучается серверное окружение, само приложение (если применимо: определяется тип, версия CMS/плагинов и разворачивается локальная копия, анализируется исходный код) и системы защиты (WAF).

WAF bypass

В контексте WAF применение решений на основе сигнатур упрощает атакующему возможность обхода WAF. Для наглядности мы часто приводим примеры, в которых происходит расщепление запроса символами, при этом запрос успешно отрабатывает на стороне веб-приложения так, будто символы расщепления не использовались:


un","ion se","lect
unIO%6e/*a*/selEC%74

Кроме того, атакующий может использовать особенности обработки запроса конечным интерпретатором, что приводит не только к пропуску атак сигнатурным методом, но и к выполнению запроса на целевом сервере:


%2f???%2f??t%20%2f???%2fp??s??
cat+/e't'c/pa'ss'wd
e'c'ho 'swd test pentest' |awk '{print "cat /etc/pas"$1}' |bash

и вот результат:

Магия Unicode
В чем разница между двумя запросами: defcon.ru/?s=waf и defcon.ru/?s=waf? Вывод по ним будет абсолютно идентичный:

Если вам показалось, что в первом запросе добавлены пробелы между символами, то вам показалось. В одном случае используется Basic Latin, в другом — Fullwidth Latin. Суть в том, что это можно использовать для обхода сигнатур WAF. Как один из примеров применения — обход фильтрации.

Известен не один десяток способов байпаса сигнатурного WAF: двойной URL-encode, смена кодировки, расщепление запроса и т.д. Некоторые из них связаны с недостатком самого решения, другие — с особенностью обработки и интерпретации запроса конечным сервисом, но, в основном, все методы обхода содержат признаки атаки, пусть и модифицированные. Для выявления таких атак мы используем машинное обучение, которое, помимо снижения до минимума количества ложных срабатываний, позволяет выявлять различные способы обхода WAF.

Ко всему прочему машинное обучение производит построение поведенческих моделей на основе реального трафика, таким образом атакующий не сможет получить аналогичные модели в собственной инфраструктуре, что значительно усложнит попытки поиска способа обхода WAF. В случае использования сигнатурного анализа атакующему достаточно выявить способ в собственной среде и воспроизвести на удаленном сервере.

Заключение

Для защиты веб-приложений от атак рекомендуется:

  • соблюдать лучшие практики и рекомендации в области безопасной разработки
  • контролировать состояние веб-окружения и потенциальных «точек входа»
  • своевременно устанавливать security-обновления
  • устанавливать лимиты на обращения к сервисам
  • использовать WAF для защиты веб-приложения
  • проводить тестирование на проникновение веб-приложения, выполнять анализ исходного кода