User Enumeration от Dungleton Security

georgy_moker

New member
10.02.2026
1
0
🕵️ User enumeration
как атакующие узнают, кто у вас в системе (и как с этим жить)

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

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

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

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

Если логин реальный - с ним уже можно что-то делать:
  • подобрать пароль (или проверить утёкший),
  • сделать правдоподобный фишинг,
  • использовать как якорь для дальнейших атак.

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

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

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

  • разные поля в JSON,
  • разные stack trace’ы в debug-режиме,
  • разные тайминги.
Отдельный привет логам и метрикам, которые пишутся только «если пользователь найден».


4️⃣ 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!
 
Мы в соцсетях:

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