MAATRIX / Блог / Сканер прошёлся по сайту: как отличить разведку от реальной атаки

Сканер прошёлся по сайту: как отличить разведку от реальной атаки

MAATRIX

Открываете access.log и видите десятки строк: /wp-admin/, /.env, /.git/config, /phpmyadmin/, /actuator/health — а на сервере нет ни WordPress, ни PHP, ни единого Java-сервиса. Первая реакция — тревога: сайт сканируют, значит, скоро взломают. На практике так выглядит фон для любого сервера с белым IP и открытым 80/443 портом — сканирование начинается в первые часы после запуска и не прекращается никогда. Разберёмся, как читать такие логи спокойно, но не пропустить момент, когда безобидный шум превращается в целенаправленную подготовку к атаке.

Что вы видите в логах, когда вас сканируют

Типичный автоматический скан оставляет узнаваемый след — набор запросов к путям, которые массово встречаются в популярных CMS, фреймворках и панелях управления, независимо от того, что реально стоит на сервере:

GET /wp-login.php HTTP/1.1
GET /wp-admin/ HTTP/1.1
GET /.env HTTP/1.1
GET /.git/config HTTP/1.1
GET /admin/ HTTP/1.1
GET /phpmyadmin/ HTTP/1.1
GET /xmlrpc.php HTTP/1.1
GET /.aws/credentials HTTP/1.1
GET /actuator/health HTTP/1.1
GET /server-status HTTP/1.1
GET /.well-known/security.txt HTTP/1.1

Быстро вытащить такие строки из nginx-логов можно одной командой:

grep -E '\.env|\.git|wp-admin|wp-login|phpmyadmin|xmlrpc|actuator|server-status' \
  /var/log/nginx/access.log | awk '{print $1, $7}' | sort | uniq -c | sort -rn | head -30

Обратите внимание на User-Agent — он часто честно называет инструмент: python-requests/2.x, Go-http-client, curl/8.x, строки Nuclei, Nikto, dirbuster/gobuster, zgrab, masscan-banner-grab. Иногда UA пустой или подделан под обычный браузер — это тоже сигнал, но сам по себе не говорит ни о чём: подделывать заголовки одинаково легко и исследователю, и школьнику с шаблонным скриптом.

Ключевой момент: почти весь этот трафик — не про вас лично. Это горизонтальное сканирование всего диапазона IPv4 по одному и тому же списку путей, и ваш сервер попадает в выборку просто потому, что у него есть IP-адрес.

Кто и зачем сканирует

За фоновым сканированием стоит несколько разных категорий источников, и большинство из них не имеют отношения к атаке на конкретно ваш сервер:

  • Индексаторы вроде Shodan, Censys, BinaryEdge — собирают карту интернета: какие порты открыты, какие баннеры отдают сервисы. Не эксплуатируют находки сами, но их база потом используется третьими лицами.
  • Исследователи и bug bounty охотники — массово прогоняют широкие диапазоны в поисках публично раскрытых уязвимостей, часто без разбора, относится ли конкретный IP к их программе.
  • Ботнеты, вербующие новые узлы — автоматически ищут уязвимые CMS, роутеры, IoT-устройства, чтобы добавить их в свою инфраструктуру, а не для того, чтобы что-то украсть у вас конкретно.
  • Преступники на этапе разведки перед атакой — здесь сканирование целенаправленное: сначала прощупывают периметр, потом решают, стоит ли атаковать дальше.

Проблема в том, что первые три категории по логам почти неотличимы от четвёртой в моменте единичного запроса. Различие проявляется не в одном событии, а в паттерне — широте, повторяемости и том, что происходит после первого касания.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Признаки обычного фонового скана

Фоновый скан почти всегда выдаёт себя сочетанием нескольких черт:

  • Широкий, но неглубокий охват. Пробуются 5–15 универсальных путей из стандартного списка, без адаптации под то, что реально отдаёт сервер. Боту всё равно, что /wp-login.php вернул 404 — он идёт дальше по списку и переходит к следующему IP.
  • Одна попытка и тишина. IP заходит один раз, получает пачку 404/403 и больше не возвращается — ни через час, ни через неделю.
  • Источник — датацентровый диапазон. Чаще всего это IP-адреса облачных провайдеров и дешёвых VPS (Hetzner, DigitalOcean, OVH, азиатские хостеры с мягкой abuse-политикой), а не резидентные адреса.
  • Нет реакции на находки. Даже если один из путей случайно ответил 200 вместо 404, скрипт массового сканирования это обычно не замечает — он не рассчитан на анализ конкретного сайта, только на статистику по всему диапазону.
  • Одновременно те же пути летят на соседние IP. Если у вас несколько серверов в одной подсети, похожий набор запросов часто приходит на все сразу, что подтверждает автоматизированный, не персонализированный характер.

Это не повод для паники и не повод писать абьюз-жалобу на каждый такой IP — их тысячи, и завтра будут новые. Держать это под контролем нужно системно, а не реагировать на каждое событие в отдельности.

Признаки целенаправленной разведки

Целенаправленная разведка перед атакой выглядит иначе — она глубже, персонализированнее и упорнее:

  • Глубина вместо ширины. После первых зондов идёт адаптация: если Server: в ответе показал версию nginx или конкретный стек (например, заголовки Laravel или конкретный CMS по favicon/статике), следующие запросы уже целятся именно в этот стек, а не идут по общему шаблону.
  • Повторяемость с конкретных IP или подсети. Один и тот же адрес или соседние адреса одной подсети/ASN возвращаются через день, через неделю — проверяют, не появилось ли что-то новое, не поменялась ли версия.
  • Последовательная логика. Сначала robots.txt и sitemap.xml, затем перебор директорий по словарю (характерный набор запросов от gobuster/ffuf с постоянным приростом на 1-2 символа в пути), затем — попытки логина именно туда, где что-то откликнулось.
  • Реакция на найденное. Если один из путей ответил 200 вместо 404 — например, случайно открытая /backup.zip или незакрытая админка — за этим следует всплеск интереса именно к этому URL: повторные обращения, попытки скачать, попытки авторизоваться.
  • Привязка по времени к внешним событиям. Разведка учащается сразу после регистрации нового домена, публикации в соцсетях, попадания в новостной инфоповод или после утечки, где мог всплыть ваш IP или поддомен.

Отдельно стоит смотреть на запросы к путям, которые не входят в стандартные словари сканеров — например, к внутреннему API-эндпоинту с нетривиальным именем или к staging-поддомену, о котором нигде публично не упоминалось. Такие запросы означают, что источник узнал о пути не из общего списка, а из конкретной утечки: истории git, старого бэкапа, случайно проиндексированной страницы, слитой документации.

Что происходит после разведки — как выглядит эскалация

Главный практический вопрос не «сканируют ли меня» — сканируют всегда, — а «переходит ли сканирование в попытку эксплуатации». Типичная цепочка эскалации выглядит так:

День 1, 03:14 — GET /wp-login.php, /admin/, /.env  (404, 404, 404)   — с IP A
День 1, 03:14 — тот же набор путей                                   — ещё с 40 разных IP (шум)
День 3, 11:02 — GET /admin/  (200 — форма логина реально существует) — с IP A
День 3, 11:03–11:40 — POST /admin/login  ×47 попыток с разными парами логин/пароль — с IP A и ещё 3 IP той же подсети
День 4 — POST /admin/login с payload вида ' OR '1'='1  (проверка на SQL-инъекцию) — с IP A

Первая строка — фон, вторая — тоже фон, просто от другого источника. А вот повтор с того же IP через два дня, да ещё с переходом от GET-разведки к POST-запросам с логин/паролем и тестовыми SQL-строками — это уже не разведка «на всякий случай», а целенаправленная последовательность.

Признаки эскалации, за которыми стоит следить:

  • переход от GET к POST/PUT на найденных эндпоинтах;
  • попытки перебора учётных данных (много 401/403 подряд с одного источника на один и тот же URL);
  • инъекционные и обходные payload'ы в параметрах запроса — кавычки, ../../, <script>, шаблоны SSTI;
  • рост частоты запросов с одного источника — переход от «раз в день» к «раз в секунду»;
  • запросы, специфичные именно для вашего стека, которых нет в стандартных словарях.

Если после разведки в течение нескольких дней ничего из этого не происходит — вероятнее всего, источник либо ушёл ни с чем, либо это был исследователь без злого умысла. Если паттерн эскалации есть — стоит переходить от наблюдения к активному реагированию, вплоть до сценария как при DDoS-атаке: первые действия, если объём запросов начинает создавать нагрузку сам по себе.

Как реагировать: практика без паранойи

Правильная реакция строится на двух уровнях: базовая гигиена, которая работает всегда, и точечное реагирование на паттерны эскалации.

Базовый уровень — не требует ручного разбора каждого скана:

  • Держите логи с ротацией и достаточной глубиной хранения (минимум 2-4 недели), чтобы было с чем сравнивать через неделю — без истории вы не увидите повторяемость.
  • Настройте автоматическую блокировку по количеству неудачных попыток в единицу времени — fail2ban для nginx с правилом на 404-шторм или на неудачные логины закрывает основной объём автоматического перебора без вашего участия.
  • Отдавайте на несуществующие «интересные» пути (/wp-admin, /.env, /phpmyadmin) короткий 444 без тела ответа в nginx — это не остановит сканер, но не тратит ресурсы на генерацию полноценной страницы ошибки:
location ~* /(wp-admin|wp-login\.php|\.env|\.git|phpmyadmin|xmlrpc\.php) {
    return 444;
}
  • Не открывайте наружу то, чего там не должно быть: /server-status, дебаг-эндпоинты, staging-окружения без базовой аутентификации. Разведка ищет именно такие огрехи, и лучшая защита — не давать ей находить.
  • Раз в неделю, а не ежедневно, просматривайте агрегированную статистику: топ IP по числу запросов, топ путей, топ кодов ответа. Разовый просмотр слишком шумный и утомительный, недельная сводка выявляет повторяющихся «клиентов» гораздо надёжнее.

Точечный уровень — включается, когда видна эскалация:

  • Если один IP или подсеть возвращаются несколько дней подряд и переходят к POST-запросам — блокируйте на уровне фаервола, не полагаясь только на fail2ban с его временным баном:
ufw deny from 203.0.113.0/24 to any port 80,443
  • Проверяйте ASN и репутацию повторяющихся адресов (whois, публичные базы репутации IP) — это помогает понять, датацентровый ли это шум или, что реже, целенаправленный источник.
  • Если найден путь, который реально ответил 200 там, где должен быть 404 — закройте его немедленно, это приоритетнее любого анализа: раскрытый бэкап или забытая админка страшнее самого факта, что её нашли.
  • Настройте алерт не на «кто-то скачал /wp-login.php», а на конкретные сигналы эскалации: серию 401 подряд к одному эндпоинту, появление SQL/XSS-паттернов в параметрах, резкий рост RPS с одного источника.

Общий чек-лист базовой защиты периметра, снижающий саму вероятность того, что разведка во что-то перерастёт, разобран в чек-листе безопасности нового сервера — сканирование неизбежно, а вот открытые двери за ним — уже вопрос вашей настройки.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Нужно ли банить IP за единичный скан стандартных путей?

Как правило нет — таких источников тысячи, ручная блокировка каждого не масштабируется и не снижает риск. Автоматический бан по частоте (fail2ban, лимиты в nginx) закрывает это без ручного участия.

Как понять, что сканер что-то реально нашёл?

Смотрите не на факт запроса, а на код ответа: 200 или 301 там, где ожидается 404, означает, что путь существует и его увидели. Это требует немедленной реакции — закрыть доступ или удалить лишнее — независимо от того, кто именно сканировал.

Стоит ли скрывать версию сервера и стек в заголовках?

Полностью скрыть не получится (это не полноценная защита, а мера снижения шума), но server_tokens off; в nginx и отсутствие явных версий в заголовках сокращают долю автоматических атак, ориентированных на конкретные версии ПО.

Разведка идёт постоянно с одной и той же подсети уже неделю — что делать?

Это уже не фон, а целенаправленный интерес. Блокируйте подсеть на фаерволе, проверяйте, не отвечал ли за это время сервер кодом 200 на что-то из проверяемых путей, и держите под особым вниманием логи ближайших дней.

Нужен ли отдельный WAF, если уже настроен fail2ban?

Fail2ban реагирует постфактум по логам, WAF фильтрует запрос до того, как он дойдёт до приложения. Для небольшого проекта связки nginx-правил и fail2ban часто достаточно; WAF имеет смысл добавлять, когда на сервере крутится что-то с реальной ценностью для атакующего — платежи, персональные данные, админка с широкими правами.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →