На аудите fintech-проекта, где OpenBao крутил ротацию database credentials и API-ключей облачных провайдеров, я ковырял OIDC-аутентификацию через Burp Suite и наткнулся на роль с явно включённым
callback_mode=direct (не дефолт - кто-то из админов выставил руками). Когда в марте 2026 вышел advisory по CVE-2026-33757 с CVSS 9.6 Critical, я проверил сценарий на тестовом стенде - воспроизвёл за полтора часа: фишинговая ссылка, один клик жертвы, и OpenBao отдаёт vault token с полным доступом к secrets engine. Без единого алерта в аудит-логе, потому что никто не настроил корреляцию IP в auth flow. Разберём механику, пошаговый сценарий эксплуатации и конкретные шаги по детектированию.Бизнес-логика атаки: зачем фиксировать сессию в secrets vault
OpenBao - open-source форк HashiCorp Vault, появившийся после смены лицензии Vault на BSL. Многие организации перетащили инфраструктуру на OpenBao именно из-за лицензионных ограничений, и теперь он централизованно хранит самое ценное: API-ключи, пароли баз данных, TLS-сертификаты, токены облачных провайдеров.Если в инстансе OpenBao есть хотя бы одна роль с явно включённым
callback_mode=direct (это не дефолт - администратор задаёт вручную), компрометация vault token через session fixation - прямой путь к credentials сервисов, обращающихся к secrets engine:- Через vault token атакующий читает database credentials, SSH-ключи, cloud provider API keys
- С этими credentials делает lateral movement без необходимости ломать каждый сервис отдельно
- При наличии write-политик подменяет секреты, внедряя backdoor credentials для persistence
- В средах с CI/CD интеграцией один vault token каскадно компрометирует весь pipeline деплоя
Анатомия CVE-2026-33757: OIDC callback без подтверждения пользователя
Уязвимость классифицирована как CWE-384 (Session Fixation): «Authenticating a user, or otherwise establishing a new user session, without invalidating any existing session identifier gives an attacker the opportunity to steal authenticated sessions.» Последствие по CWE - Gain Privileges or Assume Identity.OpenBao поддерживает аутентификацию через JWT/OIDC с несколькими режимами callback. В стандартном режиме пользователь инициирует вход, OpenBao перенаправляет в IDP, после аутентификации callback возвращается в браузер пользователя, который подтверждает вход. В direct mode (
callback_mode=direct) callback идёт напрямую в API OpenBao, минуя подтверждение в браузере.Суть проблемы: в версиях до 2.5.2 при
callback_mode=direct OpenBao не запрашивает подтверждение пользователя. Атакующий инициирует аутентификационный запрос, получает auth URL и отправляет его жертве. Жертва кликает, аутентифицируется в IDP - а OpenBao выдаёт токен в сессию, которую контролирует атакующий. Flow построен на authorization code grant, но direct mode позволяет атакующему поллить API до получения токена.Затронутый пакет по данным OSV.dev:
github.com/openbao/openbao (Go), все версии до коммита e32103951925. Фикс вошёл в релиз 2.5.2.Разбор CVSS-вектора
CVSS 3.1: 9.6 (Critical) - векторCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:L| Компонент | Значение | Что это значит на практике |
|---|---|---|
| AV:N | Network | Атака через сеть - физический доступ не нужен |
| AC:L | Low | Нет специальных условий, кроме наличия роли с direct mode |
| PR:N | None | Любой может инициировать OIDC auth request, привилегии не требуются |
| UI:R | Required | Жертва должна кликнуть по ссылке и аутентифицироваться в IDP |
| S:C | Changed | Через украденные секреты атакуются другие системы за пределами OpenBao |
| C:H | High | Полный доступ к секретам в рамках политик жертвы |
| I:H | High | Модификация секретов при наличии write-политик |
| A:L | Low | Минимальное влияние на доступность самого vault |
По EPSS, вероятность эксплуатации в течение 30 дней - 0.41% (percentile 33.76%). CISA оценивает technical impact как total при отсутствии подтверждённой эксплуатации в дикой природе (Exploitation: none) и невозможности полной автоматизации (Automatable: no). SSVC-решение: Track - мониторить.
Числа EPSS тут обманчивы. Нишевость OpenBao по сравнению с коммерческим Vault снижает интерес массовых атакующих, но для целевых атак на организации, мигрировавшие на OpenBao, вектор остаётся рабочим. Массовая эксплуатация - маловероятна, точечная - вопрос времени.
Штатный OIDC flow vs эксплуатация session fixation
Штатный OIDC flow (стандартный callback):- Пользователь запрашивает вход в OpenBao через CLI или UI
- OpenBao генерирует auth URL с параметрами
state,nonce,redirect_uri - Браузер пользователя перенаправляется в IDP (Keycloak, Okta, Azure AD)
- Пользователь аутентифицируется в IDP
- IDP возвращает authorization code в браузер пользователя через redirect
- Браузер пользователя отправляет code обратно в OpenBao
- OpenBao обменивает code на ID token, проверяет
state/nonce, выдаёт vault token - Vault token получает пользователь, инициировавший flow
- Атакующий инициирует auth request к API, получает auth URL с
stateиnonce - Атакующий отправляет auth URL жертве (фишинг, мессенджер, email)
- Жертва кликает, аутентифицируется в IDP
- IDP возвращает authorization code напрямую в API OpenBao, а не в браузер жертвы
- OpenBao привязывает vault token к сессии, инициированной атакующим
- Атакующий поллит API и получает vault token жертвы
Шаг 1. Recon - fingerprinting роли с callback_mode=direct.
Атакующий запрашивает конфигурацию OIDC-ролей. Если ACL позволяет - через
bao list auth/oidc/role, затем bao read auth/oidc/role/<name> для каждой роли. Ищем callback_mode: "direct".Шаг 2. Инициация auth flow от имени атакующего.
Код:
GET /v1/auth/oidc/oidc/auth_url?role=<TARGET_ROLE>&redirect_uri=<CALLBACK_URI> HTTP/1.1
Host: openbao.target.internal:8200
state и nonce. Атакующий сохраняет их для поллинга на шаге 5.Шаг 3. Доставка фишинговой ссылки жертве.
Auth URL выглядит как легитимная ссылка на корпоративный IDP - жертва видит знакомый экран логина Keycloak, Okta или Azure AD. Визуально ничего подозрительного: домен IDP корректный, TLS-сертификат валидный. Ни один email-фильтр не заблокирует ссылку на ваш собственный корпоративный IDP.
Шаг 4. Жертва аутентифицируется в IDP.
После ввода credentials IDP выполняет redirect с authorization code. В direct mode этот code уходит напрямую в API OpenBao, а не в браузер жертвы. Если у жертвы уже есть активная SSO-сессия в IDP - аутентификация происходит автоматически, без ввода пароля. Один клик - и всё.
Шаг 5. Атакующий поллит API для получения токена.
Bash:
# Упрощённая иллюстрация механики поллинга (не рабочий PoC).
# В реальном flow IDP доставляет authorization code напрямую в API OpenBao
# через redirect; атакующий опрашивает статус по state, не передавая code.
while true; do
RESULT=$(curl -s "https://openbao.target.internal:8200/v1/auth/oidc/oidc/poll?state=$STATE")
echo "$RESULT" | grep -q client_token && break
sleep 2
done
echo "$RESULT"
Шаг 6. Доступ к secrets engine.
Полученный token используется для операций в рамках политик жертвы:
bao kv get -mount=secret <path>, bao read database/creds/<role> и т.д.Предусловия и ограничения
Работает если:- OpenBao версии до 2.5.2
- Существует хотя бы одна OIDC-роль с
callback_mode=direct - Жертва имеет активную SSO-сессию в IDP или готова аутентифицироваться
- OpenBao API доступен атакующему по сети
- Все роли используют стандартный callback mode
- IDP принудительно запрашивает consent для каждой сессии по Client ID, используемому OpenBao
- OpenBao обновлён до 2.5.2 (добавлен экран подтверждения для direct-логинов)
- Сетевая сегментация блокирует доступ атакующего к API OpenBao
Место в цепочке атаки
CVE-2026-33757 сидит между initial access и credential access:- Recon - обнаружение OpenBao инстанса, fingerprinting OIDC-ролей с
callback_mode=direct - Initial Access (T1190) - эксплуатация уязвимого OIDC flow через фишинг
- Credential Access (T1539) - получение vault token с правами жертвы
- Privilege Escalation - если политики жертвы включают admin-уровень, атакующий получает полный контроль над secrets engine
- Lateral Movement (T1550.004) - credentials из secrets engine (database passwords, API keys, SSH keys) открывают доступ к другим системам
- Exfiltration - массовое чтение секретов через vault API
Детектирование через аудит-логи OpenBao
OpenBao ведёт аудит-лог всех операций через audit device. Для поиска session fixation нужны три IoC:IoC 1: Auth request и token issuance с разных IP. Запрос на
/v1/auth/oidc/oidc/auth_url приходит с одного remote_address (атакующий), а IDP фиксирует аутентификацию с другого IP (жертва). Корреляция request.id и remote_address в аудит-логах выявляет расхождение.IoC 2: Polling-паттерн на callback endpoint. Множественные запросы к
/v1/auth/oidc/oidc/callback с одними и теми же параметрами state/nonce в короткий промежуток. Штатный flow - один callback, а не серия.IoC 3: Использование token с нехарактерного IP. После получения vault token операции с секретами выполняются с IP, отличного от обычного для этого пользователя. Корреляция
auth.client_token с remote_address в аудит-логах обнаруживает аномалию.Для SIEM-интеграции: фильтруйте записи по
path: "auth/oidc/*", группируйте по request.id и remote_address. Аномалия - два и более уникальных IP в рамках одного auth flow. Для Elastic SIEM 8.x+ правило строится через EQL-запрос по event.action и source.ip с correlation window 5–10 минут.Сравнение мер устранения
| Мера | Закрывает уязвимость | Побочные эффекты | Время внедрения |
|---|---|---|---|
| Обновление до 2.5.2 | Да - полностью | Требует тестирования в staging | 1-4 часа |
| Удаление callback_mode=direct | Да - полностью | Ломает automated auth flows, зависящие от direct mode | 15 минут |
| Consent prompt в IDP | Частично - снижает риск | Дополнительный шаг при каждом входе всех пользователей | 30 минут |
| Сетевая сегментация API | Нет - снижает attack surface | Не устраняет саму уязвимость, ограничивает доступ | 2-8 часов |
Чеклист устранения CVE-2026-33757
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Минилаб для отработки
Требования к окружению:- Docker и Docker Compose
- RAM: 4 ГБ минимум, 8 ГБ рекомендуется (OpenBao + Keycloak + Burp Suite)
- ОС: Linux (Ubuntu 22.04+), macOS или Windows с WSL2
- Burp Suite Community/Pro или mitmproxy для перехвата HTTP-запросов
- Сеть: локальная, интернет не нужен после скачивания образов
- Поднять OpenBao в dev-режиме:
docker run -d --name openbao -p 8200:8200 openbao/openbao server -dev. Dev-режим автоматически unseal'ит vault и выдаёт root token в stdout - Поднять Keycloak как IDP:
docker run -d --name keycloak -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak start-dev - Настроить в Keycloak: создать realm, OIDC client с redirect URI на callback endpoint OpenBao, тестового пользователя
- Сконфигурировать OIDC auth method в OpenBao: включить
auth/oidc, создать роль сcallback_mode=direct, указатьoidc_discovery_urlот Keycloak, привязатьtoken_policies - Открыть Burp Suite, настроить proxy для перехвата запросов к OpenBao API на порту 8200
- В терминале (имитация атакующего) выполнить GET-запрос на
/v1/auth/oidc/oidc/auth_urlс нужной ролью, сохранитьstateиnonceиз ответа - В другом браузере (имитация жертвы) перейти по полученному auth URL, аутентифицироваться в Keycloak
- Наблюдать в Burp: callback приходит в API, token выдаётся в сессию «атакующего»
- Проверить доступ: использовать полученный token для
bao kv get
Session fixation - уязвимость, которая на бумаге выглядит элементарно: не привязал session ID к инициатору, не запросил подтверждение - и auth flow развалился. CWE-384 существует больше пятнадцати лет. И при этом проект уровня OpenBao - штука, которая по определению хранит credentials всей организации - выпускает auth-метод с
callback_mode=direct без подтверждения пользователя. Это не рядовая бага, а архитектурный просчёт в auth-flow.EPSS показывает 0.41%, CISA ставит Exploitation: none - и может сложиться ощущение, что угроза теоретическая. Но развернуть PoC - вопрос двух часов, доставка фишинговой ссылки - одного письма, а auth URL ведёт на легитимный домен IDP, который не заблокирует ни один email-фильтр.
Для организаций, мигрировавших с Vault после смены лицензии HashiCorp, проверка занимает две минуты:
bao list auth/oidc/role и bao read auth/oidc/role/<name>. Две минуты вместо расследования инцидента с утечкой всех secrets. Я ожидаю, что в ближайший год мы увидим аналогичные баги в других форках и альтернативах Vault - молодые проекты наследуют кодовую базу, но не всегда наследуют зрелость security review.