Guardduty, фишинг. Часть 2 из 2.
Что произошло на самом деле
Схема простая до слёз:
Пользователь отправил сообщение с URL -> x*****.cn
|
Сервис обработки контента внутри кубера получил вебхук(?)
|
Функция(?) PaymentWebhookProcessor внутри POD-а попыталась резолвить домен
(логика: ищет превью/изображения по URL-ам в тексте)
|
DNS-запрос к x*****.cn с EKS ноды, на которой запущен под
|
GuardDuty: ALARM
Никакой малвари. Нода не скомпрометирована. Credentials не угнаны.
Просто сервис резолвит любой домен из пользовательского контента - а юзер прислал фишинговую ссылку.
Фишинг не удался (дополнительно логи смотрел).
Несколько часов расследования, CloudTrail, CloudWatch, ECR history, git blame - ответ лежал в логах приложения и нашёлся бы за 15 минут, если бы я туда полез первым делом.
Что реально плохо и надо починить
Само расследование закончилось словами "малвари нет", но по ходу вскрылись настоящие проблемы 🚬.
- SSRF
PaymentWebhookProcessor резолвит произвольные URL из пользовательского контента без какой-либо валидации.
Это означает, что любой клиент может прислать:
http://169.254.169.254/latest/meta-data/
И сервис спокойно попробует его резолвнуть - прямо с production ноды, у которой есть IAM-роль со повышенными правами (это вообще, бл, отдельный разговор какого рожна нода имела доступ к некоторым AWS ресурсам).
Фикс очевидный - блокировать приватные диапазоны перед любым исходящим запросом:
169.254.0.0/16 (AWS metadata endpoint)
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
127.0.0.0/8
- GuardDuty будет шуметь вечно
Пока сервис зачем-то резолвит пользовательские URL без фильтрации - каждый раз, когда кто-то пришлёт фишинговую ссылку, GuardDuty будет стрелять алёртом. Это шум, который убивает доверие к алёртингу.
Решение: AWS Route 53 Resolver DNS Firewall с managed threat lists.
- AWSManagedDomainsMalwareDomainList
- AWSManagedDomainsAggregateThreatList
Известные вредоносные домены блокируются до DNS-резолва автоматически, без ручных списков.
https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resolver-dns-firewall-managed-domain-lists.html
- URL-резолвинг в основном процессе
Длиннее задача, но правильная: вынести резолвинг URL в изолированный асинхронный воркер с ограниченным egress.
Без доступа во внутреннюю сеть. Без IAM-роли с правами на всё.
Выводы и итоги:
- в логи приложения надо идти первым. Не после нескольких часов инфра-форензики.☔️
- ретеншн CloudWatch-логов для EKS control plane 84 часа - маловато. Нода жила 4 дня, ранние события уже недоступны. Надо поднять. Не критикал, но надо бы.
- сервисы, которые резолвят URL из пользовательского контента, будут встречать фишинг. Это не вопрос если, это вопрос когда. Надо документировать и обрабатывать проактивно, а не разбираться в панике с High severity алёртом.
- SSRF - это не гипотетическая угроза, это прямая дыра в production при текущей архитектуре.
- кто дает права EKS нодам на доступ к AWS ресурсам, то негодяй, нельзя так
- с одной стороны я переживал тогда, что потратил много времени на расследование, копая изначально не туда, с другой стороны рад, ведь без полной картины происходящего я не смог бы понять были ли скомпроментированы креды или нет, был ли хак или нет, а так вроде и пополнил знания
- используйте сервисы AWS, многие из них хорошо помогают в траблшутинге, пусть и стоят денег
False positive закрыт, но работы добавилось.
- - -
В последствии все косяки были закрыты, все Security/AWS бест практисы внедрены.
Все потенциальные известные "дыры" закрыты, PII защищены, даже инвесторы спали спокойно после детальнейшнего постмортема.