РАЗБОР Статья

Уязвимость password reset: разбор CVE и пентест

Сергей Попов
Сергей Попов Red Team · 6,6 тыс. сообщений
Подписаться
742
[ обложка статьи ]
Режим чтения
Вскрытый конверт с восковой печатью в виде ключа на чёрном антистатическом коврике, разрез сделан скальпелем, рядом гравировка с кодом уязвимости CVE и приглушённая палитра с акцентом на алом цвете...


На пентесте IAM-инфраструктуры SaaS-провайдера я потратил два часа на recon и fingerprinting стека - а account takeover занял 90 секунд. Один POST к эндпоинту сброса пароля, и сервер принял новый пароль администратора без email-подтверждения. Не zero-day, не цепочка из пяти уязвимостей - одна пропущенная проверка состояния в потоке reset-credentials. Разработчики тестировали happy path, а про альтернативный канал просто забыли.

Русскоязычные источники покрыли обе CVE в новостном формате по 500-700 слов - без PoC, без методологии тестирования, без паттернов атак. Ниже - разбор обеих CVE, три паттерна эксплуатации password reset без верификации и пошаговый чек-лист для Burp Suite.

Бизнес-логика атаки: зачем ломают password reset​

Password reset - единственный легитимный механизм смены credentials без знания текущего пароля. Для атакующего это прямой путь к Valid Accounts (T1078, Initial Access / Persistence / Privilege Escalation): не нужен брутфорс (T1110.001, Password Guessing) или фишинг - достаточно логической ошибки в одном API-эндпоинте. Подробнее - в нашем подробном разборе атаки на аутентификацию.

Типовая цепочка монетизации выглядит так:
  1. Recon - сбор email-адресов через утечки, LinkedIn или username enumeration (T1589.001, Credentials)
  2. Exploit Public-Facing Application (T1190, Initial Access) - эксплуатация бага в password reset
  3. Account takeover - смена пароля целевого аккаунта, получение валидной сессии
  4. Privilege escalation - если скомпрометирован admin, атакующий контролирует платформу целиком
  5. Impact - кража данных, lateral movement внутри инфраструктуры, деплой ransomware
По OWASP Top 10 (2021) это пересечение A01:2021 (Broken Access Control) и broken authentication. Корневые CWE: CWE-640 (Weak Password Recovery Mechanism for Forgotten Password) - слабый механизм восстановления, и CWE-288 (Authentication Bypass Using an Alternate Path or Channel) - обход аутентификации через альтернативный канал.

Вектор: AV:N/AC:L/AT:N/PR:N/UI:N - сетевая атака, низкая сложность, без привилегий, без взаимодействия пользователя. Воздействие на конфиденциальность, целостность и доступность - высокое по всем трём параметрам.

Корневая причина - CWE-288 (Authentication Bypass Using an Alternate Path or Channel): эндпоинт /api/v1/auth/force-reset-password принимал анонимные запросы и не проверял ни текущий пароль, ни reset-токен при сбросе пароля системного администратора. POST с target username и новым паролем - аккаунт скомпрометирован. Уязвимы все версии SmarterMail до билда 9511.

Почему эта CVE - абсолютный приоритет при пентесте:
  • CISA KEV: добавлена 26 января 2026, дедлайн патча 16 февраля 2026, помечена как связанная с ransomware-кампаниями
  • EPSS: 0.9654, percentile 0.9988 - Top 0.12% по вероятности эксплуатации среди всех CVE в базе FIRST.org
  • CISA SSVC Decision: Act - патчить немедленно. Эксплуатация активная, автоматизируемая, технический импакт полный
  • PoC: публичный репозиторий MaxMnMl/smartermail-CVE-2026-23760-poc на GitHub
  • Nuclei template: CVE-2026-23760.yaml в projectdiscovery/nuclei-templates
Нашли SmarterMail на периметре? Fingerprinting версии и проверка эндпоинта: nuclei -t http/cves/2026/CVE-2026-23760.yaml -u https://target-mail.com. Если патч невозможен прямо сейчас - WAF-правило на блокировку POST к /api/v1/auth/force-reset-password и ограничение доступа к административным интерфейсам по IP-whitelist.

CVSS 9.1 (CRITICAL) по CVSS 3.1: вектор AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N - без привилегий, без взаимодействия пользователя, высокий импакт на конфиденциальность и целостность.

Корневая причина - CWE-640 (Weak Password Recovery Mechanism for Forgotten Password): некорректная проверка состояния в потоке reset-credentials. Атакующий отправлял специально сформированный запрос, и аутентификационная сессия перескакивала напрямую к этапу обновления пароля. Токен действия, который в штатном сценарии приходит на email, не требовался. По данным бюллетеня Red Hat, риск распространяется в том числе на административные аккаунты.

Тут интересный момент: по CISA SSVC решение - Track (мониторить). Эксплуатация - none на момент оценки, автоматизируемость - yes, технический импакт - total. То есть пока не ломают, но когда начнут - будет больно.
Временная мера до патча: отключить Forgot Password в каждом realm через Realm Settings -> Login -> Forgot password. Настройка per realm - одного глобального переключателя нет, придётся пройтись по каждому.

В том же релизе Keycloak 26.7.2 закрыты ещё шесть уязвимостей, включая CVE-2026-15571 (CVSS 7.3, HIGH) - предсказуемый хеш при привязке аккаунтов, позволяющий account takeover через вредоносный OIDC-клиент (CWE-341, Predictable from Observable State). Если Keycloak не обновлён до 26.7.2, уязвим не только password reset.

Fingerprinting Keycloak на пентесте: версию можно вытащить через /auth/realms/master/.well-known/openid-configuration, заголовки HTTP-ответа или HTML-страницу логина. Дальше - проверка потока reset-credentials в Burp Repeater: запрашиваете сброс пароля через UI, перехватываете все запросы в Proxy, пробуете отправить запрос установки нового пароля без токена из email. Штатный поток требует валидный action token - если сервер принимает запрос без него, это и есть подтверждение уязвимости.

CVE password reset 2026: сравнение​

ПараметрCVE-2026-23760 (SmarterMail)CVE-2026-18963 (Keycloak)
CVSS9.3 (CRITICAL, CVSS 4.0)9.1 (CRITICAL, CVSS 3.1)
CWECWE-288CWE-640
ПривилегииНе требуются (PR:N)Не требуются (PR:N)
ВзаимодействиеНе требуется (UI:N)Не требуется (UI:N)
Уязвимые версииДо билда 9511До 26.7.2 (upstream)
CISA KEVДа (ransomware)Нет
EPSS0.9654 (Top 1%)0.0318 (выше медианы)
Публичный PoCДаДа (46 звёзд)
Nuclei templateДаДа

Broken authentication пентест: паттерны атак на password reset​

1792209175262.webp

Конкретные CVE - это хорошо, но есть и повторяющиеся паттерны в кастомных реализациях логики восстановления пароля. Три из них я вижу регулярно.

Password reset без верификации: утечка токена в API​

Этот паттерн не привязан к конкретному CVE - встречается в кастомных приложениях. По данным OnSecurity, на реальном пентесте API возвращал reset-токен прямо в теле JSON-ответа на запрос сброса. Атака - два HTTP-запроса: POST /api/auth/request-password-reset с email жертвы, затем POST /api/auth/reset-password с полученным токеном и новым паролем. Account takeover без доступа к почте.
JSON:
{
  "message": "If an account exists, you will receive reset instructions.",
  "token": "8e8d6a18759f2b06f3ba43b8538c7cf707537d69226cf48f151e0816c2f99291"
}
Перевод сообщения:
JSON:
{
  "message": "Если аккаунт существует, вы получите инструкцию по сбросу.",
  "token": "8e8d6a18759f2b06f3ba43b8538c7cf707537d69226cf48f151e0816c2f99291"
}
Поле message говорит "получите инструкции по email", а токен уже в ответе. Красивый фантик, а внутри - полный доступ. Бонус: если токен возвращается только для зарегистрированных аккаунтов, наличие/отсутствие поля token позволяет перечислять пользователей (username enumeration).

Второй подтип - утечка через API misconfiguration. По данным Vaadata, на пентесте ecommerce-приложения API комментариев к товарам возвращал все поля user-объекта из БД, включая token_reset. Атакующий инициировал сброс пароля для целевого email, затем дёргал любой эндпоинт, возвращающий данные этого пользователя, и получал свежий токен - вместе с хешем пароля и email-адресом.

Как искать: в Burp Proxy изучите тело ответа на каждый запрос к /forgot-password, /reset-password и связанным эндпоинтам. Ищите поля token, reset_token, code, otp, key. Проверяйте не только JSON - токен может валяться в HTML как hidden input, в заголовках ответа или в URL редиректа.

Host header injection password reset​

Приложение генерирует ссылку сброса, используя заголовок Host из HTTP-запроса. Если сервер не валидирует Host - атакующий подменяет его на свой домен, жертва получает письмо со ссылкой https://attacker.com/reset?token=abc123. Клик - и токен улетает на сервер атакующего GET-параметром. Это password reset poisoning в классическом виде.
Код:
POST /forgot-password HTTP/1.1
Host: attacker.com
Content-Type: application/x-www-form-urlencoded

csrf=qxoCDf28hFqnF2xP6HtGiIhnDFHmryPm&username=carlos
Атака требует действия жертвы (UI:R в CVSS), что снижает итоговый score по сравнению с UI:N-вариантами. Но давайте честно: процент открытия писем от легитимного сервиса обычно высок, так что UI:R как смягчающий фактор - штука условная.

Варианты обхода валидации Host в Burp Repeater:
  • Прямая замена Host на свой домен
  • Заголовки X-Forwarded-Host, X-Forwarded-For, X-Original-URL
  • Двойной Host-заголовок - некоторые reverse-proxy пропускают второй
  • Параметры в теле запроса: по данным Vaadata, на одном пентесте JSON-тело содержало параметр baseurl, который напрямую формировал ссылку сброса. Серверная валидация через Python urlparse обходилась payload формата legitimate-domain.com@attacker.com - парсер принимал это за userinfo-часть URL

IDOR в password reset и race condition​

IDOR (Insecure Direct Object Reference): берёте reset-токен, выданный для вашего аккаунта, и подставляете в запрос смены пароля чужой user_id или email. Если сервер не проверяет привязку токена к конкретному пользователю - account takeover. Проверяется тривиально: два тестовых аккаунта, один токен, подмена идентификатора в Burp Repeater.

Race condition: через Turbo Intruder отправьте 20-50 параллельных запросов на сброс пароля для одного аккаунта. Цель - проверить, генерируется ли несколько валидных токенов одновременно и остаётся ли старый токен рабочим после создания нового. Если да - окно атаки расширяется, а одноразовость токена фактически не работает. Тест занимает 5 минут, но часто вскрывает broken access control в восстановлении доступа, который другие проверки пропускают.

Тестирование восстановления пароля: чек-лист для пентеста​

1792209208125.webp

Fingerprinting и recon​

  • Определить стек: кастомная реализация или IAM-платформа (Keycloak, Auth0, Okta, FusionAuth)
  • Для известных платформ - fingerprinting версии и сверка с NVD/nuclei-templates
  • Собрать все эндпоинты reset-flow: /forgot-password, /reset-password, /api/auth/reset, /verify-token, /force-reset-password
  • Проверить наличие Nuclei-шаблонов для обнаруженной платформы и версии

Анализ токена и rate limiting​

📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме

Host header и race condition проверки​

  • Подмена Host, X-Forwarded-Host, двойной Host-заголовок
  • Параметры в теле: baseurl, redirect_url, callback
  • Race condition через Turbo Intruder: 20-50 параллельных запросов на сброс
  • Username enumeration: сравнить ответы для существующего и несуществующего email по HTTP-коду, времени ответа (timing attack), тексту сообщения и наличию полей в JSON

Логика восстановления пароля: оформление находки в отчёте​

1792209231017.webp

Для каждого типа уязвимости password reset - свой CVSS-вектор:

Тип находкиCVSS-векторОриентир CVSSCWE
Полный обход аутентификации (CVE-2026-23760)AV:N/AC:L/PR:N/UI:N9.1+CWE-288
Обход верификации email (CVE-2026-18963)AV:N/AC:L/PR:N/UI:N9.1CWE-640
Token disclosure в ответе APIAV:N/AC:L/PR:N/UI:N9.0+CWE-640, CWE-200
Host Header InjectionAV:N/AC:L/PR:N/UI:R7-8CWE-640
OTP-брутфорс без rate limitAV:N/AC:L/PR:N/UI:N7-9CWE-640

Указывайте все применимые CWE - каждая описывает отдельный аспект уязвимости. В PoC-секции отчёта приводите конкретные HTTP-запросы: метод, путь, заголовки, тело, ответ сервера с временными метками. Для CVE-2026-18963 и CVE-2026-23760 ссылка на идентификатор CVE и зафиксированная версия - хороший контекст, но не замена PoC. Приложите HTTP-трафик, подтверждающий успешную эксплуатацию именно в тестируемой инфраструктуре (кастомные патчи или WAF могут закрывать уязвимость даже на формально уязвимой версии).

За последний год я разбирал больше двадцати реализаций password reset - от стартапов до enterprise на Keycloak. В большинстве случаев разработчики тестировали happy path (получил письмо -> кликнул -> сменил пароль), но не проверяли, что произойдёт, если атакующий пропустит шаги или пойдёт альтернативным каналом. CVE-2026-18963 - проверку состояния в потоке reset-credentials просто забыли. CVE-2026-23760 - эндпоинт force-reset-password существовал как альтернативный канал, про который не вспомнили при проектировании контроля доступа.

Итог для CVE-2026-23760: EPSS 0.9654, CISA KEV, ransomware - из-за одного POST без credentials.

Я уверен, что количество подобных CVE вырастет: приложения переносят аутентификацию на IAM-платформы, но кастомизируют потоки без security review state machine. Стандартные сканеры логические ошибки в потоке состояний не ловят - нужен ручной анализ, и это единственное, что по-прежнему отделяет ручной пентест от автоматического сканирования в контексте password reset. Если хочешь повторить шаги в контролируемой инфре - лаба по broken auth на HackerLab (https://hackerlab.pro).
Полезно

Комментарии

0