Как ФБК* сами слили все данные оппозиции в открытый доступ
* — Фонд борьбы с коррупцией включён в реестр НКО, выполняющих функции иностранного агента, по решению Министерства юстиции РФ от 09.10.2019; организация признана экстремистской, её деятельность запрещена на территории России по решению Мосгорсуда от 09.06.2021.
Привет! Здесь я хочу указать на возможную причину, почему были слиты данные зарегистрировавшихся в УГ и предупредить, что ФБК* на несколько недель в июне была открыта, как эта калитка в меме. Сразу после того, как эта дыра была обнаружена, я написал ФБК*, и доступ до инфраструктуры они починили. Пишу об этом сейчас — уже после того, как набор почт от УГ был выставлен на продажу, а затем слит — по двум причинам: считаю недостаточным простое умалчивание происходившего и происходящего, (и понимаю, что писать об этом нужно было раньше), но сам ФБК* самостоятельно не сильно хочет говорить о том, что происходило у них с безопасностью в середине-конце июня.
Сразу дам дисклеймер — я мало разбираюсь в информационной безопасности, а все, что здесь откопал — продукт внимательности, небольшого опыта пользования k8s, метода «почему бы и нет» и чистой удачи.
Как было найдено
На почту мне пришло сообщение с доменом «rus.vote» с темой «Умное голосование», что изначально показалось подозрительным: какой-то непонятный, короткий домен, не напомнивший что-то, что использовал бы ФБК*. Первой же идеей в этот момент было сначала найти домен в Google, и она увенчалась успехом, ведь на второй странице поисковика красовалась проиндексированная KubeWebView — вебпанель для доступа до инфраструктуры Kubernetes.
Прошу заметить одну интересную деталь про этот результат — он начинается с www — эта ошибка в конфигурации домена в сервисе дашборда, а значит таких доменов, как www.rus.vote, должно быть больше. Вот еще примеры доменов, что удалось найти, которые указывали на сервис вебпанели и спокойно искались в Google/Duck по запросу «Kubernetes Web View», сейчас они все кидают 404:
Здесь показан более поздний процесс поиска в DuckDuckGo
Что было найдено
Что открывается человеку, который зашел в вебпанель Kubernetes? — Достаточно много информации о состоянии системы, железе, участвующем в кластере, логам запущенных сервисов, секретов (если те не были скрыты), значений в environment’е,… Первое, что я увидел были staging кластер, на котором было запущено много разных сервисов и удобная кнопка экспорта в формат tsv или yml в зависимости от данных:
Все поды, запущенные на кластере ФБК*
Из всех подов, что я обнаружил, самыми интересными оказались:
Сервис ganimed — в логах было много почт, которым отправлялись письма с шаблоном «emails/email_confirm.html», «emails/email_singer_observer_confirm.txt»
Сервис headquarters — в логах опять почты и упоминание shtab@navalny.com
Другие поды: в основном всегда пара или тройка сервисов из фронта и бэка на django
Secrets и ConfigMaps
Логи ganimed
Это оказалось одной из самых интересных находок-комбинаций факторов: на бэке не был отключен дебаг, KubeWebView не смог скрыть почты, разработчики ФБК* решили логгировать все почты, на которые они высылали письма, в том числе и от УГ.
Для небольшого теста (reality check, а вдруг нашел кластер для разработки, и все не так плохо) я послал запрос на регистрацию на УГ с помощью почты «test@test.com»
В логе я сразу обнаружил:
ganimed-django-rq-685597bfd4-k2jsh main 2021-06-24T17:43:43.822640701Z 20:43:43 high: landing.tasks.email.send_confirmation_email_async(confirm_url='https://votesmart.appspot.com/email-confirm/91c30631f88e4b6b8d65/', html_template='emails/email_confirm.html', subject='ÐожалÑйÑÑа, подÑвеÑдиÑе поÑÑÑ', to='test@test.com', txt_template='emails/email_confirm.txt') (8c2e27a7-2bde-4b0f-b759-7d1952a69b7b)
Видеть это было больно, а таких логов там было на 40 дней. Вверху окна с логами в дашборде можно было указать фильтр и кол-во линий для вывода: таким образом можно было стащить хорошее количество почт, и данных когда и что именно на эту почту было выслано.
Секреты в ConfigMaps
Следующее, что я решил откопать — были секреты. Их положение было сразу известно — это ресурс Secrets. К счастью для ФБК*, все секреты в ресурсе Secrets были скрыты — на это указывал issue в репо KubeWebView и наши находки:
apiVersion: v1
data:
CELERY_BROKER_URL: '**SECRET-CONTENT-HIDDEN-BY-KUBE-WEB-VIEW**'
DJANGO_DB_HOST: '**SECRET-CONTENT-HIDDEN-BY-KUBE-WEB-VIEW**'
DJANGO_DB_NAME: '**SECRET-CONTENT-HIDDEN-BY-KUBE-WEB-VIEW**'
DJANGO_DB_PASS: '**SECRET-CONTENT-HIDDEN-BY-KUBE-WEB-VIEW**'
DJANGO_DB_USER: '**SECRET-CONTENT-HIDDEN-BY-KUBE-WEB-VIEW**'
FB_PASSWORD: '**SECRET-CONTENT-HIDDEN-BY-KUBE-WEB-VIEW**'
FB_USERNAME: '**SECRET-CONTENT-HIDDEN-BY-KUBE-WEB-VIEW**'
Но. у разработчиков есть всегда другой источник переменных данных — environment, или в интерпретации от Kubernetes — ConfigMaps. В итоге разработчики ФБК* успешно использовали их для хранения секретов… удобно видимо. Иронично, что в конфигмапах elections-api я обнаружил это:
apiVersion: v1
data:
ANTICAPTCHA_CLIENT_KEY: 8c12***4a
CANARY_HOST: https://canary.navalny.com
CANARY_SERVICE_KEY: 1e***79
CIK_API_HOST: https://cik-api.navalny.com
DB_HOST: 10.***
DB_NAME: ele***i
DB_PASS: O***8
DB_PORT: '5432'
DB_USER: django
ELASTIC_HOST: ela***db
ELASTIC_PORT: '9200'
FROM_EMAIL: info@rus.vote
# ирония:
MAILGUN_API_KEY: 3***1d
Как и другие данные — доступы до внутренних сервисов; доступы до БД; ключи от сервисов Amazon, Google, ботов Telegram; пароли от Facebook и Instagram — ключ от mailgun оказался рабочим и часто используемым.
Выводы и пожелания
Эта калитка (а точнее несколько) в врата оппозиции висела на Google и других поисковиках больше, чем 10 дней на момент починки дыры безопасности:
23 июн 2021 11:05:54 GMT как пример — на одной из таких страниц была указана дата 13 июня
В связи с этим хотелось бы получить ответ на несколько простых вопросов:
Кто, когда и сколько раз ходил на этот ресурс извне ФБК*
Какие данные могли быть слиты кроме того, что я представил в статье
И самое важное: почему вы молчите?
Сейчас было слито порядка 20 тысяч (в источниках фигурирует цифра 200 тысяч) почт, сколько данных еще в запасе у людей с корыстными мотивами — неизвестно.
P.S.: как уже было сказало, я написал ФБК* сразу как обнаружили эту дыру (Thursday, June 24th, 2021), они даже отписались о том, что приняли меры и сменили ключи в конфигмапах. Эта статья с ними не согласована.
P.P. S.: с звездочкой при названии организации я не согласен.