PDA

Просмотр полной версии : User Enumeration от Dungleton Security


georgy_moker
10.02.2026, 13:11
User enumeration
как атакующие узнают, кто у вас в системе (и как с этим жить)

Автор: Dungleton Security
Для кого: все, кто хоть раз получал письмо «восстановите пароль» и думал


«а я тут вообще при чём?»


Зачем атакующему перечислять пользователей

User enumeration - Это разведка.

Прежде чем подбирать пароль или слать фишинг, атакующему нужно понять простую вещь:
какие учётные записи вообще существуют.

Если логин реальный - с ним уже можно что-то делать:

подобрать пароль (или проверить утёкший),

сделать правдоподобный фишинг,

использовать как якорь для дальнейших атак.

Если логин выдуманный — он бесполезен.
Поэтому первая задача — отделить реальные аккаунты от мусора.

Мы в Dungleton регулярно видим, как это делают на практике, чаще всего применяя к нам(
Если атакующий знает несколько реальных имён (а они почти всегда где-то есть — сайт, LinkedIn, конференции), дальше всё механически: берём список имён, прогоняем через форму регистрации, отмечаем «занято».
Даже если:


одинаковый HTTP-код,

одинаковый текст,
остаются:


разные поля в JSON,

разные stack trace’ы в debug-режиме,

разные тайминги.
Отдельный привет логам и метрикам, которые пишутся только «если пользователь найден».

OSINT: вы сами всё рассказали
Очень часто формат логинов вообще не нужно угадывать.

Он уже есть:


на странице «О команде»,

в PDF-презентации,

в примерах в документации,

на скриншотах из интерфейсов,

в докладах с конференций.
Пара имён + один пример логина = гипотеза по формату.
Дальше — перебор и проверка.



Даже если это «просто примеры» и «не прод» — атакующему всё равно.

Timing-атаки: когда ошибки одинаковые, а время — нет
Даже если вы сделали всё «правильно»:

один текст,

один код ответа,
можно спалиться по времени обработки.

Типичный сценарий:

несуществующий логин → быстрый отказ;

существующий логин → поиск пользователя + проверка хеша пароля.
Если используется bcrypt / scrypt / argon2 — разница может быть десятки или сотни миллисекунд.

Этого достаточно:


делается серия запросов,

считается среднее время,

логины с «длинным» ответом помечаются как валидные.
Что реально помогает

При user not found всё равно выполнять хеширование (на заглушке).

Следить, чтобы логирование и метрики не добавляли разницу.

Добавлять jitter или фиксированную задержку там, где это допустимо.

Не забывать, что API и UI — разные поверхности атаки.
Здесь классика жанра:

Правильно:



«Если аккаунт с таким email существует, мы отправили письмо»

На практике:


«Пользователь не найден»,

письмо отправляется только для существующих,

разный тайминг ответа.

Регистрация и «логин занят»
Проверка занятости логина в реальном времени — почти всегда утечка.

Особенно если:


нет капчи,

нет лимитов,

нет задержек.
Лучше:


проверять занятость только при финальной отправке,

ограничивать частоту,

не говорить явно, почему регистрация не прошла.
Про шаблоны логинов и «случайные» имена
Форматы name.family, n.family, family.n, name.f удобны.
И именно поэтому опасны.

Как только они где-то засветились вместе с реальными именами, атакующий получает:


формат,

кандидатов,

способ проверки.
Даже если это было «просто для примера».
Итог
User enumeration — это не уязвимость.
Но позволяя её воспроизводить, мы сделали атаку проще.

Чем меньше различий:

в текстах,

в кодах,

во времени ответа,
и чем меньше реальных примеров и шаблонов в открытом доступе —
тем меньше полезных сигналов вы отдаёте наружу.

Мы в Dungleton Security регулярно проверяем такие вещи на наших системах - и почти всегда что-то находится.

Пишите мне нам на email, если у вас есть вопросы, с Вами были Эмили Браун и Павел Чернов, до встречи на PHDays 2026!