РАЗБОР
Статья
Уязвимость password reset: разбор 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-эндпоинте. Подробнее - в нашем подробном разборе атаки на аутентификацию.Типовая цепочка монетизации выглядит так:
- Recon - сбор email-адресов через утечки, LinkedIn или username enumeration (T1589.001, Credentials)
- Exploit Public-Facing Application (T1190, Initial Access) - эксплуатация бага в password reset
- Account takeover - смена пароля целевого аккаунта, получение валидной сессии
- Privilege escalation - если скомпрометирован admin, атакующий контролирует платформу целиком
- Impact - кража данных, lateral movement внутри инфраструктуры, деплой ransomware
Вектор: 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
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. То есть пока не ломают, но когда начнут - будет больно.
- EPSS: 0.0318, percentile 0.8784 - выше медианы
- Уязвимые версии: upstream Keycloak до 26.7.2; RHBK 26.4 до 26.4.15; RHBK 26.6 до 26.6.6
- PoC: Snizi/CVE-2026-18963-Exploit, prot0tw/Keycloak_CVE-2026-18963_PoC, gman0x00/keycloak-CVE-2026-18963 с Docker-площадкой и patch diff analysis
- Nuclei template:
CVE-2026-18963.yamlв projectdiscovery/nuclei-templates
В том же релизе 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) |
|---|---|---|
| CVSS | 9.3 (CRITICAL, CVSS 4.0) | 9.1 (CRITICAL, CVSS 3.1) |
| CWE | CWE-288 | CWE-640 |
| Привилегии | Не требуются (PR:N) | Не требуются (PR:N) |
| Взаимодействие | Не требуется (UI:N) | Не требуется (UI:N) |
| Уязвимые версии | До билда 9511 | До 26.7.2 (upstream) |
| CISA KEV | Да (ransomware) | Нет |
| EPSS | 0.9654 (Top 1%) | 0.0318 (выше медианы) |
| Публичный PoC | Да | Да (46 звёзд) |
| Nuclei template | Да | Да |
Broken authentication пентест: паттерны атак на password reset
Конкретные 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
Варианты обхода валидации Host в Burp Repeater:
- Прямая замена
Hostна свой домен - Заголовки
X-Forwarded-Host,X-Forwarded-For,X-Original-URL - Двойной Host-заголовок - некоторые reverse-proxy пропускают второй
- Параметры в теле запроса: по данным Vaadata, на одном пентесте JSON-тело содержало параметр
baseurl, который напрямую формировал ссылку сброса. Серверная валидация через Pythonurlparseобходилась 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 в восстановлении доступа, который другие проверки пропускают.
Тестирование восстановления пароля: чек-лист для пентеста
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
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
Логика восстановления пароля: оформление находки в отчёте
Для каждого типа уязвимости password reset - свой CVSS-вектор:
| Тип находки | CVSS-вектор | Ориентир CVSS | CWE |
|---|---|---|---|
| Полный обход аутентификации (CVE-2026-23760) | AV:N/AC:L/PR:N/UI:N | 9.1+ | CWE-288 |
| Обход верификации email (CVE-2026-18963) | AV:N/AC:L/PR:N/UI:N | 9.1 | CWE-640 |
| Token disclosure в ответе API | AV:N/AC:L/PR:N/UI:N | 9.0+ | CWE-640, CWE-200 |
| Host Header Injection | AV:N/AC:L/PR:N/UI:R | 7-8 | CWE-640 |
| OTP-брутфорс без rate limit | AV:N/AC:L/PR:N/UI:N | 7-9 | CWE-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).
AI-выжимка
по разделам
Тезисы статьи скоро
Статья читается полностью. Тезисы со ссылками на разделы появятся позже.
Содержание
Codeby Academy
Практика и мастерство
От основ до продвинутого — программы для практиков Codeby.
Перейти к курсу →
Продолжить чтение
Следующий разбор
Введение в OWASP WSTG
Комментарии
0