Макросъёмка платы сервера с треснувшим разъёмом и лазерной гравировкой «CVE-2026-33757 · SESSION FIXATION» на радиаторе, подсвеченная лампой лупы на чёрном антистатическом коврике. Красный индикато...


На аудите 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 деплоя
По MITRE ATT&CK цепочка: Exploit Public-Facing Application (T1190, Initial Access)Steal Web Session Cookie (T1539, Credential Access) - получение vault token через перехват OIDC callback → доступ к Cloud Accounts (T1078.004) → lateral movement с полученными credentials (T1550.004).

Анатомия 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:NNetworkАтака через сеть - физический доступ не нужен
AC:LLowНет специальных условий, кроме наличия роли с direct mode
PR:NNoneЛюбой может инициировать OIDC auth request, привилегии не требуются
UI:RRequiredЖертва должна кликнуть по ссылке и аутентифицироваться в IDP
S:CChangedЧерез украденные секреты атакуются другие системы за пределами OpenBao
C:HHighПолный доступ к секретам в рамках политик жертвы
I:HHighМодификация секретов при наличии write-политик
A:LLowМинимальное влияние на доступность самого 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):
  1. Пользователь запрашивает вход в OpenBao через CLI или UI
  2. OpenBao генерирует auth URL с параметрами state, nonce, redirect_uri
  3. Браузер пользователя перенаправляется в IDP (Keycloak, Okta, Azure AD)
  4. Пользователь аутентифицируется в IDP
  5. IDP возвращает authorization code в браузер пользователя через redirect
  6. Браузер пользователя отправляет code обратно в OpenBao
  7. OpenBao обменивает code на ID token, проверяет state/nonce, выдаёт vault token
  8. Vault token получает пользователь, инициировавший flow
Эксплуатация через callback_mode=direct:
  1. Атакующий инициирует auth request к API, получает auth URL с state и nonce
  2. Атакующий отправляет auth URL жертве (фишинг, мессенджер, email)
  3. Жертва кликает, аутентифицируется в IDP
  4. IDP возвращает authorization code напрямую в API OpenBao, а не в браузер жертвы
  5. OpenBao привязывает vault token к сессии, инициированной атакующим
  6. Атакующий поллит API и получает vault token жертвы
Вся разница - в direct mode IDP callback идёт в API, а не в браузер. OpenBao не запрашивает подтверждение: кто инициировал flow, тот и получает token. Session fixation через OIDC в чистом виде.

Шаг 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
OpenBao возвращает URL для аутентификации в IDP с параметрами 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"
Как только жертва завершает аутентификацию, OpenBao отдаёт vault token в ответ на polling-запрос.

Шаг 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
OPSEC-заметка: атака оставляет следы в аудит-логах OpenBao (auth request, token creation) и логах IDP. Два разных source IP обращаются к одному auth flow - это IoC при корректно настроенном мониторинге. Фишинговый URL ведёт на легитимный домен IDP, что затрудняет обнаружение на стороне email security, но не на стороне vault.

Место в цепочке атаки​

CVE-2026-33757 сидит между initial access и credential access:
  1. Recon - обнаружение OpenBao инстанса, fingerprinting OIDC-ролей с callback_mode=direct
  2. Initial Access (T1190) - эксплуатация уязвимого OIDC flow через фишинг
  3. Credential Access (T1539) - получение vault token с правами жертвы
  4. Privilege Escalation - если политики жертвы включают admin-уровень, атакующий получает полный контроль над secrets engine
  5. Lateral Movement (T1550.004) - credentials из secrets engine (database passwords, API keys, SSH keys) открывают доступ к другим системам
  6. Exfiltration - массовое чтение секретов через vault API
Атака особенно опасна в средах, где OpenBao хранит credentials для CI/CD pipeline (Jenkins, GitLab CI), cloud provider API keys (AWS IAM, GCP Service Accounts) или database root passwords. Один vault token каскадно компрометирует десятки сервисов - это не локальная бага, а точка входа для захвата инфраструктуры.

Детектирование через аудит-логи 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Да - полностьюТребует тестирования в staging1-4 часа
Удаление callback_mode=directДа - полностьюЛомает automated auth flows, зависящие от direct mode15 минут
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-запросов
  • Сеть: локальная, интернет не нужен после скачивания образов
Сценарий воспроизведения:
  1. Поднять OpenBao в dev-режиме: docker run -d --name openbao -p 8200:8200 openbao/openbao server -dev. Dev-режим автоматически unseal'ит vault и выдаёт root token в stdout
  2. Поднять 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
  3. Настроить в Keycloak: создать realm, OIDC client с redirect URI на callback endpoint OpenBao, тестового пользователя
  4. Сконфигурировать OIDC auth method в OpenBao: включить auth/oidc, создать роль с callback_mode=direct, указать oidc_discovery_url от Keycloak, привязать token_policies
  5. Открыть Burp Suite, настроить proxy для перехвата запросов к OpenBao API на порту 8200
  6. В терминале (имитация атакующего) выполнить GET-запрос на /v1/auth/oidc/oidc/auth_url с нужной ролью, сохранить state и nonce из ответа
  7. В другом браузере (имитация жертвы) перейти по полученному auth URL, аутентифицироваться в Keycloak
  8. Наблюдать в Burp: callback приходит в API, token выдаётся в сессию «атакующего»
  9. Проверить доступ: использовать полученный token для bao kv get
Верификация фикса: обновить контейнер OpenBao до 2.5.2, повторить шаги 6–8. На шаге 7 должен появиться экран подтверждения, блокирующий автоматическую выдачу token без явного согласия пользователя.

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.
 
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab

Похожие темы

🚀 Первый раз на Codeby?
Гайд для новичков: что делать в первые 15 минут, ключевые разделы, правила
Начать здесь →
🧭 Навигатор · ИБ 2026
Не знаешь, какой трек твой?
5 направлений ИБ, реальные зарплаты и точка входа для каждого — в одном треде.
JuniorSenior+
100K → 600K+ ₽ /мес
Открыть навигатор →
🔴 Свежие CVE, 0-day и инциденты
То, о чём ChatGPT ещё не знает — обсуждаем в реальном времени
Threat Intel →
💼 Вакансии и заказы в ИБ
Pentest, SOC, DevSecOps, bug bounty — работа и проекты от проверенных компаний
Карьера в ИБ →

HackerLab