Условие
Пользователи одного сайта стали жаловаться, что к их аккаунтам кто-то получил доступ. Помоги проанализировать access-лог и понять, как это могло произойти.
Решение
План анализа access-лога
Типичный лог nginx/apache:
1.2.3.4 - alice [05/May/2026:10:23:11 +0000] "GET /api/me HTTP/1.1" 200 ...
Ищем аномалии в нескольких разрезах.
1. Поиск brute-force
# Топ IP по числу 401/403 ответов
awk '$9 ~ /(401|403)/ {print $1}' access.log | sort | uniq -c | sort -rn | head
# Топ IP по числу POST /login
grep 'POST /login' access.log | awk '{print $1}' | sort | uniq -c | sort -rn | headЕсли один IP делает >100 POST /login в минуту — brute-force или credential stuffing.
2. Credential Stuffing
Атака: ботнет использует утёкшие пары email:password с других сайтов. Признаки:
- Много разных юзернеймов, по одной попытке с каждого IP — но всего тысячи разных IP (IP rotation).
- HTTP 200 на /login (успех!) среди множества 401 — это и есть взломанные аккаунты.
# Успешные логины с подозрительных IP-стран / ASN
grep 'POST /login.*200' access.log | awk '{print $1}' | sort -u3. Session Hijacking
Признаки:
- Один и тот же
Cookie: session=...приходит с разных IP/User-Agent в течение часов. - Сессионный ID не должен «перепрыгивать» между странами без
/logout+/login.
# Извлекаем session-cookie (если в логе доступен)
awk -F'session=([^;]+)' '/session=/ {print $2, $1}' access.logЕсли фиксируется одинаковая сессия с двух IP в одно время — кто-то её украл.
4. IDOR (Insecure Direct Object Reference)
Признаки:
- Пользователь
alice(/api/me?user=alice) меняет параметр наbobи получает данные:GET /api/profile?id=12345 HTTP/1.1 200 GET /api/profile?id=12346 HTTP/1.1 200 ← перебор GET /api/profile?id=12347 HTTP/1.1 200 - Серия запросов с инкрементальными
idот одного аккаунта/IP.
# Перебор IDOR
awk '/api\/profile\?id=/ {print $1, $7}' access.log | sort | uniq -c | sort -rn | head5. Утечка токенов через GET-параметры
Антипаттерн: GET /reset-password?token=ABCDEF → токен попадает в Referer при переходе на внешний сайт, в логи прокси/CDN, в браузерную историю.
# Поиск чувствительных параметров в URL
grep -E 'token=|password=|api_key=|access_token=' access.logЕсли такие токены в логах есть — это потенциальный канал утечки. Лекарство: токен в POST body / в HTTP header / одноразовый.
6. Reuse одинакового token-параметра
Если в логе один и тот же reset-token используется несколько раз (а должен быть single-use) — баг в приложении.
7. CSRF-атаки
Признак: запрос с Referer: другого домена + Cookie: session=... валидной сессии. Защита — CSRF-токены.
8. SSRF / открытые редиректы
Если ?redirect=https://evil.com принимается без проверки — фишинг через домен компании.
grep -E 'redirect=https?://' access.log | awk -F'redirect=' '{print $2}' | awk -F'&' '{print $1}' | sort -u9. XSS-индикаторы
grep -E '<script|javascript:|onerror=|onload=' access.logХотя они часто URL-encoded — %3Cscript%3E. Декодируем перед анализом.
10. Подозрительные User-Agent
awk -F'"' '{print $6}' access.log | sort | uniq -c | sort -rn | headcurl/, python-requests/, Go-http-client/ или пустой UA — не клиенты браузера.
Структура отчёта
- Что нашли: конкретный вектор (например, IDOR в
/api/profile). - Доказательство: строки лога с timestamp.
- Затронутые пользователи: список ID/email.
- Хронология: когда впервые и когда последний раз.
- Рекомендации: изменить логику, инвалидировать сессии, force password reset.
Конкретные гипотезы
Если в логе видны:
?token=...в reset → утечка через Referer / CDN-кеш.- Серия
GET /api/users/<id>/privateс инкрементами → IDOR. - Одинаковая
Cookie: session=...с разных стран → session hijacking (XSS / открытый Wi-Fi без HSTS). - Burst POST /login → brute-force / credential stuffing → нет MFA или слабая политика паролей.
Подводные камни
- Логи могут быть отредактированы атакующим (если он root). Сверяйте с centralized SIEM.
- NAT и proxy. Один публичный IP — это сотни пользователей за CGNAT (мобильные операторы). Не по одному IP блокировать.
- User-Agent легко подделать. «Mozilla/5.0» — не доказательство, что это браузер.
- Тайминг. Логи в локальной таймзоне сервера; смешивать с UTC-логами CDN — путаница.
- GDPR / закон о персданных. При публикации деталей маскируйте IP/email.
HTTP 200≠ «успех логина». Для SPA логин может быть 200 с error в JSON. Проверяйте полеbody_sizeили конкретный эндпоинт.- «Виновный IP» может быть Tor exit node или VPN — не персонализирует пользователя.
- Логи без
Cookie-полей — ничего не скажешь о сессиях. Включайте логирование cookie-заголовков (с маскированием) для security-investigations.
Эталонный ответ
Чек-лист в access-логе:
- Brute-force / credential stuffing — топ IP по 4xx на /login.
- Session hijacking — одна
session=cookie с разных IP. - IDOR — серия запросов с инкрементами в
id/uuid. - Утечка токенов через GET-параметры (
token=,api_key=). - Подозрительные UA / страны / burst-паттерны.
Лечение: MFA + rate-limit + CSRF-токены + перенос секретов из URL в headers/body + invalidate-all-sessions для жертв.