Взлом CircleCI в январе 2023 года: как один заражённый ноутбук заставил всех клиентов менять секреты
Команда KAI Lab · · 9 мин чтения
4 января 2023 года CircleCI попросила всех клиентов срочно сменить все секреты, которые хранились в сервисе. Причина — взлом: атакующий заразил ноутбук инженера, украл его сессию единого входа (SSO), уже прошедшую двухфакторную проверку, и 22 декабря 2022 года выгрузил переменные окружения, токены и ключи клиентов, а ключи шифрования к ним достал из памяти работающего процесса.
Антивирус вредонос не заметил. О взломе CircleCI узнала не от своих систем, а от клиента: 29 декабря он сообщил о подозрительной активности своего OAuth-токена GitHub. Полный отчёт вышел 13 января 2023 года. К этому дню меньше пяти клиентов сообщили, что через украденные секреты кто-то добрался до их систем.
Главное о взломе в одной таблице
| Вопрос | Ответ |
|---|---|
| Когда | ноутбук заражён 16 декабря 2022, разведка в проде 19 декабря, выгрузка данных 22 декабря |
| Как вошли | вредонос на ноутбуке инженера украл cookie сессии SSO, которая уже прошла 2FA |
| Почему хватило одного ноутбука | инженер по работе мог выпускать токены доступа к продакшену |
| Что унесли | переменные окружения, токены и ключи клиентов из части баз и хранилищ |
| Что попросили у клиентов | сменить все секреты в CircleCI |
| Ущерб у клиентов | меньше 5 клиентов сообщили о доступе к их сторонним системам (на 13 января) |
Хронология взлома CircleCI
| Дата (UTC) | Что произошло |
|---|---|
| 16 декабря 2022 | На ноутбук инженера попадает вредонос. Антивирус его не видит |
| 19 декабря | Атакующий ведёт разведку в проде |
| 22 декабря | Выгрузка данных клиентов. Это последняя запись о чужой активности в проде |
| 29 декабря | Клиент сообщает о подозрительной активности своего OAuth-токена GitHub |
| 30 декабря | Подтверждено: токен этого клиента скомпрометирован |
| 31 декабря, 04:00 | CircleCI из осторожности начинает менять OAuth-токены GitHub всех клиентов |
| 4 января 2023 | Установлены масштаб и путь атаки. В 16:35 отключён доступ сотрудника, в 18:30 доступ к проду закрыт почти всем, к 22:30 заменены все потенциально затронутые хосты прода |
| 5 января, 02:30 | Письма клиентам: сменить все секреты. По тихоокеанскому времени это ещё 4 января |
| 5–6 января | Отозваны все API-токены проектов и личные API-токены, созданные до 5 января. Вместе с Atlassian заменены токены Bitbucket |
| 7 января, 07:30 | Закончена замена OAuth-токенов GitHub. Вечером вместе с AWS начато оповещение владельцев затронутых ключей AWS |
| 13 января | Опубликован отчёт об инциденте |
Как атакующий попал внутрь
- Вредонос на рабочем ноутбуке. 16 декабря ноутбук инженера CircleCI был заражён, антивирус угрозу не распознал.
- Кража cookie сессии. Инженер уже вошёл через SSO и прошёл второй фактор, дальше сессия живёт как cookie в браузере. Вредонос её украл, и атакующий стал для систем CircleCI этим инженером, работая из другого места. Второй фактор у него никто не спросил: вход уже состоялся.
- Повышение доступа. У инженера по работе было право выпускать токены доступа к продакшену. С ним атакующий попал в часть производственных систем, а 22 декабря выгрузил секреты клиентов.
Ни подобранного пароля, ни уязвимости в коде CircleCI. Атакующему хватило легального доступа одного сотрудника.
Почему шифрование не спасло
Секреты клиентов лежали зашифрованными. Но сервис, который отдаёт их джобам, обязан уметь их расшифровать, значит, ключ есть в памяти работающего процесса. Атакующий с доступом к проду достал ключи оттуда. Шифрование на диске защищает от украденного диска или бэкапа, но не от того, кто уже внутри с правами на прод. Поэтому ключи шифрования держат там, куда инженер с обычным доступом к проду не дотянется: в KMS или HSM, откуда ключ не выходит, а каждое обращение пишется в журнал.
Что CircleCI сделала в первые дни
- Закрыла прод почти для всех сотрудников и заменила все хосты, которые могли быть затронуты.
- Вместе с GitHub, Atlassian и AWS заменила или отозвала токены клиентов. Замена OAuth-токенов GitHub шла неделю, с 31 декабря по 7 января, хотя CircleCI работала с GitHub над лимитами API.
- Научила MDM и антивирус блокировать поведение этого вредоноса, а оставшимся с доступом к проду добавила дополнительную аутентификацию (step-up), чтобы одной украденной сессии с 2FA было мало.
- Выпустила скрипт, который находит все секреты клиента в CircleCI, и открыла журнал аудита для всех тарифов.
Что пришлось делать клиентам
CircleCI просила заменить всё, что хранилось в сервисе: OAuth-токены GitHub, Bitbucket и GitLab, API-токены проектов и личные, переменные окружения проектов и контекстов, SSH-ключи проектов и deploy keys, токены раннеров.
Потом — журналы своих систем. В первом оповещении CircleCI просила смотреть с 21 декабря, в отчёте окно расширилось: с 16 декабря, дня заражения ноутбука, до дня, когда вы закончили замену секретов. К отчёту приложили индикаторы компрометации — IP-адреса атакующего, файлы PTX-Player.dmg и PTX.app, домен potrax[.]com — и совет искать в журнале аудита GitHub неожиданные события вроде repo.download_zip.
На практике «сменить все секреты» значит найти каждый секрет и каждое место, где он используется, и заменить его, не уронив деплой. Тот же вывод — утёкший секрет скомпрометирован, пока его не заменили, — был и после взлома Codecov в 2021 году.
Уроки для DevOps
1. Сессия после входа — такой же секрет, как пароль
2FA проверяет человека в момент входа, а cookie сессии потом работает без него. Для доступа к проду нужны короткие сессии, привязка к устройству и повторная проверка перед опасными действиями. CircleCI после взлома так и делает: снижает доверие к сессиям и добавляет факторы аутентификации.
2. CI — самое ценное место для атакующего
В CI лежат ключи от облака, реестров, баз и репозиториев, то есть от всего прода сразу. Чем меньше в нём долгоживущих секретов, тем меньше можно украсть. CircleCI сама советует OIDC: джоба получает короткоживущий токен и меняет его у облака на временные ключи.
# джоба CircleCI: OIDC-токен джобы вместо статического ключа AWS
echo "$CIRCLE_OIDC_TOKEN" > /tmp/oidc-token
export AWS_ROLE_ARN="arn:aws:iam::123456789012:role/circleci-deploy"
export AWS_WEB_IDENTITY_TOKEN_FILE=/tmp/oidc-token
export AWS_ROLE_SESSION_NAME="circleci-${CIRCLE_BUILD_NUM}"
aws sts get-caller-identity # в Arn будет assumed-role/circleci-deploy, а не пользователь IAMТокен $CIRCLE_OIDC_TOKEN действует час после выпуска, а в доверительной политике роли можно разрешить её только джобам конкретного проекта через условие на поле sub. В хранилище CI при такой схеме нет ключа, который работал бы вечно.
3. Доступ к проду — по запросу и на время
Право выпускать токены к проду было у инженера постоянно. Значит, любая украденная сессия сразу стоила всего. CircleCI обещает сделать права «более эфемерными». У себя это называется доступом по запросу (just-in-time): запросил, получил на час, всё записано в журнал.
4. Замена секретов — отрепетированная процедура, а не аврал
Если в день инцидента вы впервые выясняете, где лежит ключ и кто его владелец, замена займёт недели. Нужен инвентарь: секрет, где хранится, кто владелец, как заменить, что сломается. Начать можно с возраста ключей:
aws iam list-access-keys --user-name ci-deploy \
--query 'AccessKeyMetadata[].[AccessKeyId,Status,CreateDate]' --output tableЕсли ключу CI два года, замена в день инцидента станет для него первой. Ключи в коде «потому что репозиторий приватный» — отдельная история, её показывает утечка Uber 2016 года.
5. Следите, как используются ваши токены
CircleCI узнала о взломе от клиента, который заметил странную активность своего токена. Журналы аудита GitHub и облака, алерты на вход с незнакомых адресов и списки разрешённых IP — ваша сигнализация на случай, если поставщика взломают раньше, чем он это поймёт.
6. Инцидент — отказ системы, а не человека
CircleCI прямо пишет: ноутбук взломали у одного сотрудника, но инцидент безопасности — это отказ системы. Один заражённый ноутбук не должен открывать секреты всех клиентов. Так же разбирают и обычные сбои, подробнее — в статье про blameless-постмортем.
Что проверить у себя завтра:
- какие секреты в CI живут без срока и сколько им лет;
- можно ли перевести на OIDC хотя бы деплой в облако;
- у кого постоянный доступ к проду и можно ли выдавать его на время;
- сколько займёт замена всех секретов CI, если начать прямо сейчас.
Реши сам
Два вопроса по этому взлому. Ответы — под спойлером.
Вопрос 1. Почему двухфакторная аутентификация не остановила атакующего?
- У инженера не было 2FA
- Украли cookie сессии, которая уже прошла 2FA, — повторно второй фактор не спрашивается
- Атакующий подобрал пароль
- Инженер сам передал доступ
Показать ответ
Верный ответ — 2. В отчёте прямо сказано: вредонос украл действующую сессию SSO, подкреплённую 2FA. Защита — короткие сессии, привязка к устройству и дополнительная проверка перед доступом к проду. Её CircleCI и добавила после взлома.
Вопрос 2. Секреты клиентов хранились зашифрованными. Почему это не помогло?
- Шифрование было слабым
- Ключи шифрования атакующий достал из памяти работающего процесса
- Секреты лежали в открытом виде в логах
- Атакующий подобрал ключ перебором
Показать ответ
Верный ответ — 2. Сервис, который расшифровывает секреты для джоб, держит ключи в памяти. Шифрование на диске защищает от кражи диска или бэкапа, но не от того, кто получил доступ к проду.
Частые вопросы
Что случилось с CircleCI в январе 2023 года? Атакующий заразил ноутбук инженера CircleCI, украл его сессию SSO и с его правами выгрузил из прода переменные окружения, токены и ключи клиентов. 4 января CircleCI попросила всех клиентов заменить все секреты, 13 января опубликовала отчёт.
Сколько клиентов пострадало? Менять секреты CircleCI просила всех. На 13 января меньше пяти клиентов сообщили, что через украденные секреты кто-то получил доступ к их сторонним системам.
Виноват ли инженер, чей ноутбук заразили? CircleCI так не считает: в отчёте инцидент назван отказом системы. Вредонос прошёл мимо антивируса, а права одного сотрудника позволяли дотянуться до секретов клиентов. Исправляли именно это — права, сессии и обнаружение.
Пройти похожий сбой самому
В симуляторе DevOps KAI Lab вы год работаете DevOps-инженером в выдуманной компании Qoima. Шестой месяц посвящён CI/CD, в нём есть разбор взлома CircleCI и тикет «Пароль базы в логе джобы»: подрядчик присылает скриншот лога деплоя с паролем, и нужно выяснить, как секрет туда попал. Другие разборы собраны в подборке 18 сбоев, которые должен знать DevOps-инженер.
Начать можно бесплатно: тест навыков и первые задания первого месяца.
Источники
- CircleCI, Rob Zuber. CircleCI Jan 4, 2023 security incident report, 13.01.2023 — хронология, путь атаки, действия, индикаторы компрометации, планы.
- CircleCI. CircleCI security alert: Rotate any secrets stored in CircleCI, 04.01.2023, обновления по 13.01.2023 — список секретов для замены, окно проверки журналов.
- CircleCI Discuss. Incident Report: January 4th, 2023 Security Incident, 13.01.2023 — дата публикации отчёта.
- CircleCI Docs. Using OpenID Connect tokens in jobs —
CIRCLE_OIDC_TOKEN, срок действия, полеsub. - AWS Docs. Using an IAM role in the AWS CLI — раздел Assume role with web identity, переменные
AWS_ROLE_ARNиAWS_WEB_IDENTITY_TOKEN_FILE.