open atlas
↑ К треку
Основы безопасности SECF · 03 · 01

От паролей к MFA

Пароли не масштабируются: их переиспользуют, дампы питают credential stuffing, а ошибки хранения превращают один пробой в миллионы взломанных аккаунтов. MFA помогает, но его рутинно фишат; держат удар только phishing-resistant факторы вроде passkey.

SECF Middle ◷ 15 min
Уровень
ОсновыJuniorMiddleSenior

Пробой случается на форуме, о котором никто в твоей команде даже не слышал. Через две недели твой собственный эндпоинт логина получает 40 000 запросов в час, каждый — реальная пара email и пароль, и примерно один из 200 возвращает 200 OK. Тебя не взламывали. Взломали твоих пользователей — где-то ещё, годы назад — а они переиспользовали тот же пароль у тебя. Атакующий ничего не ломал. Он проиграл список. Это credential stuffing, и сегодня это самый частый способ угона аккаунтов — именно потому, что он обходит любую защиту, предполагающую, что атакующему придётся ломать твою систему.

К концу урока ты поймёшь, почему пароли не масштабируются, как именно обходят MFA на практике и какие факторы действительно устойчивы к фишингу.

Почему пароли не масштабируются

Пароль — это общий секрет: его знает пользователь и знает твой сервер. Эта симметрия и есть вся проблема. Пользователь переиспользует секрет на десятках сайтов, поэтому его безопасность не выше, чем у худшего сайта, на котором он его когда-либо вводил, — а тот сайт тебе не подконтролен. Исследования больших корпусов утечек дают переиспользование паролей выше 50% пользователей; один этот факт и есть причина, по которой дамп с никак не связанного сервиса становится атакой на тебя.

Три сбоя усиливают друг друга:

  • Переиспользование → credential stuffing. Атакующие берут миллиарды утёкших пар email:пароль (одна только «Collection #1» содержала ~773 млн уникальных email) и проигрывают их по твоему логину через сменяющиеся прокси. Доля успеха в 0,1–2% звучит ничтожно, пока не умножишь на миллионы попыток: 0,5% попаданий на 10 млн попыток — это 50 000 скомпрометированных аккаунтов, а в логах просто много валидных входов.
  • Подбор → brute force и спрей. Против одного аккаунта помогают rate-лимиты и блокировки. Password spraying их обходит: пробуешь один распространённый пароль (Winter2024!) по десяти тысячам аккаунтов, так что ни один аккаунт не триггерит блокировку. Счётчики на аккаунт не срабатывают; нужна детекция по источнику и по паттерну учёток.
  • Ошибки хранения → офлайн-взлом. Если твоё хранилище паролей утекло, у атакующего пошёл отсчёт. Открытый текст или несолёный MD5/SHA-1 — и вся таблица вскрывается за часы на ширпотребной GPU-ферме, делающей десятки миллиардов попыток в секунду. Корректно выбранный медленный, солёный, memory-hard хеш (Argon2id, scrypt или bcrypt) — вот что покупает тебе время: соль убивает заранее посчитанные rainbow-таблицы и заставляет работать по каждому аккаунту, а намеренная медлительность ограничивает скорость перебора.

Зрелый рефлекс: считай своё хранилище паролей уже утёкшим и проектируй хеш так, чтобы даже тогда взлом был экономически болезненным. И считай каждый успешный вход возможным атакующим с валидным паролем — именно эту брешь и должен закрыть второй фактор.

Чем помогает MFA — и как его обходят

Многофакторная аутентификация требует свидетельства из более чем одной категории: что-то, что ты знаешь (пароль), что-то, что у тебя есть (телефон, ключ безопасности), что-то, чем ты являешься (отпечаток). Суть не в том, что какой-то один фактор силён; суть в том, что атакующему теперь нужно скомпрометировать две несвязанные вещи разом. Против массового credential stuffing это разгром: у бота есть пароль, но нет второго фактора, и автоматический угон умирает. Microsoft и Google оба сообщали, что MFA блокирует заметно больше 99% автоматических попыток компрометации. Это число реально — и здесь же люди перестают думать, что и есть опасная часть.

MFA не бинарно. Факторы образуют лестницу силы, и целевой атакующий (в отличие от массового бота) рутинно ломает слабые ступени:

  • Одноразовые коды по SMS одновременно фишабельны и перехватываемы. SIM-swap — социнженерия оператора, чтобы перенести номер жертвы на SIM атакующего, — доставляет код прямо ему. SMS лучше, чем ничего, и куда лучше против ботов, но NIST годами не рекомендует его как основной фактор.
  • TOTP-приложения (6-значный код, меняющийся каждые 30 секунд, RFC 6238) убирают оператора из цепочки — секрет живёт на устройстве. Но код по-прежнему то, что пользователь может прочитать и ввести, а значит, его можно обманом заставить ввести код на поддельном сайте.
  • Push-уведомления добавляют тап, но вносят MFA-усталость: засыпать жертву запросами в 3 ночи, пока она не нажмёт «подтвердить», лишь бы это прекратилось. Так взломали Uber и других. Number-matching (в запросе показывается число, которое надо ввести) притупляет приём, но не убирает человека из цепочки.

Обход, связывающий слабые ступени воедино, — это фишинг-прокси реального времени (Evilginx, Modlishka и им подобные). Жертва попадает на пиксель-в-пиксель прокси твоего логина. Она вводит пароль — прокси ретранслирует его на настоящий сайт. Настоящий сайт просит TOTP-код — прокси ретранслирует запрос, жертва вводит код, прокси ретранслирует и его. Настоящий сайт выдаёт cookie сессии, и прокси крадёт её. У атакующего теперь аутентифицированная сессия, и ни пароль, ни код ему больше не нужны. Любой фактор, который пользователь вводит, проигрываем через этого «человека посередине» — вот вся причина, по которой «phishing-resistant» это отдельное, более трудное свойство.

Почему это работает

Почему одноразовый код не останавливает фишинг-прокси, если он валиден всего 30 секунд? Потому что прокси работает вживую. Он не сохраняет код на потом — он ретранслирует его в тот же миг, когда жертва его вводит, внутри тех же 30 секунд, на подлинный сайт. OTP делает ровно свою работу (доказывает свежий код) и всё равно проигрывает, потому что в протоколе ничто не привязывает код к тому, с каким сайтом пользователь на самом деле говорит. Эта недостающая привязка — между учёткой и origin — и есть та самая брешь, которую закрывают phishing-resistant факторы.

Phishing-resistant факторы

Фактор устойчив к фишингу, когда кража того, что ввёл пользователь, не даёт атакующему ничего — потому что вводить нечего. Механизм — криптография на открытых ключах, привязанная к origin, стандартизированная как WebAuthn / FIDO2 и доехавшая до пользователей как passkey и аппаратные ключи безопасности.

Вот значимый механизм. При регистрации аутентификатор (YubiKey или защищённый элемент в телефоне) генерирует новую пару ключей, привязанную к твоему точному origin, https://yourbank.com. Приватный ключ никогда не покидает устройство; сервер хранит только публичный. При входе сервер шлёт случайный challenge; аутентификатор подписывает его приватным ключом, а браузер включает настоящий origin в то, что подписывается. Из этого единственного решения выпадают два следствия:

  1. Нет общего секрета, который можно сфишить. Пользователь не вводит ничего, что атакующий мог бы проиграть. Подпись для одного challenge бесполезна для следующего.
  2. Привязка к origin убивает прокси. Если жертва на yourbank.evil.com, браузер подписывает этот origin — и твой сервер, ожидающий yourbank.com, отвергает подпись. Ретранслятор Evilginx рушится, потому что учётка отказывается работать где-либо, кроме подлинного сайта. Этого свойства лишены SMS, TOTP и push.
ФакторКатегорияОстанавливает массовый stuffing?Останавливает фишинг реального времени?Чем ломается
Только парольЗнаюНетНетПереиспользование, дампы, взлом
SMS OTPИмею (слабо)ДаНетSIM-swap, ретранслятор
TOTP-приложениеИмеюДаНетПрокси реального времени (введённый код)
Push + number-matchИмеюДаЧастичноMFA-усталость, ретранслятор
Passkey / ключ безопасностиИмею + являюсьДаДаКража устройства + локальная разблокировка

Зрелый вывод — тиражируемый по уровню угрозы. Любой MFA крушит проблему массовых ботов, поэтому самая дешёвая крупная победа — включить какой-нибудь второй фактор всем. Но для аккаунтов, которые важны — админы, финансы, любой с доступом к проду, — вводимых факторов мало, потому что это ровно те аккаунты, которые живой атакующий будет фишить в реальном времени. Там планка — phishing-resistant WebAuthn. И не дай MFA стать единой точкой отказа: слабое восстановление доступа («потерял телефон, пришлите код на старый номер») — та задняя дверь, что тихо понижает твой сильнейший фактор до слабейшего.

Выбери лучший вариант

Твоих админов постоянно фишат: атакующие поднимают поддельный прокси логина, ретранслируют пароль и TOTP-код в реальном времени и крадут cookie сессии. TOTP MFA уже включён. Выбери фикс, который это действительно закрывает.

Викторина

Твой логин получает миллионы попыток с реальными парами email/пароль, с долей успеха ~0,5% и без блокировки ни одного аккаунта. Что это и каков корневой включатель?

Викторина

Почему passkey (WebAuthn) побеждает фишинг-прокси реального времени, а TOTP-код — нет?

Расставь шаги по порядку

Упорядочь эти факторы аутентификации от слабейшего к сильнейшему против целевого атакующего, управляемого человеком:

  1. 1 Только пароль (переиспользуем, фишабелен, взламываем)
  2. 2 SMS OTP (фишабелен + уязвим к SIM-swap)
  3. 3 TOTP-приложение (фишабелен: код вводится)
  4. 4 Push + number-matching (стоек к усталости, но ретранслируем)
  5. 5 Passkey / ключ безопасности (привязан к origin, устойчив к фишингу)
Вспомните перед уходом
  1. 01
    Объясни, почему пароли не масштабируются, и назови три усиливающих друг друга сбоя.
  2. 02
    Что делает фактор устойчивым к фишингу и почему SMS, TOTP и push не дотягивают до этой планки, а passkey — дотягивает?
Итог

Пароли не масштабируются, потому что это общие секреты, которые пользователи переиспользуют: пробой на любом сайте становится credential stuffing против твоего, где миллиарды утёкших пар проигрываются, и даже доля попаданий в доли процента даёт массовый угон аккаунтов. Спрей обходит блокировки на аккаунт, а утёкшее хранилище взламывается быстро, если оно не хешировано медленной, солёной, memory-hard функцией (Argon2id, scrypt, bcrypt). MFA — ответ на stuffing: он блокирует больше 99% автоматических угонов, — но он не бинарен. SMS фишабелен и уязвим к SIM-swap, TOTP и push ретранслируются фишинг-прокси реального времени, которые пересылают введённый код и крадут cookie сессии, а push добавляет спам MFA-усталости. Фактор, который действительно держит удар против целевого человека, — это phishing-resistant WebAuthn: passkey или ключ безопасности подписывает привязанный к origin challenge приватным ключом, который никогда не покидает устройство, так что подпись, сделанная на поддельном домене, отвергается, и нет секрета для ретрансляции. Поэтому зрелая позиция тиражируема: включи любой MFA всем, чтобы убить ботов, требуй passkey для важных аккаунтов, хешируй так, будто хранилище уже утекло, и следи, чтобы восстановление доступа не стало задней дверью в обход всего этого.

Практика

Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.

вспомнитьприменитьуглубить0 из 6 завершено
Связанные уроки
углубляется в

Что-то непонятно?

Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.

хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.