Как я обошел 2FA и захватил учетки пользователей

D2

Администратор
Регистрация
19 Фев 2025
Сообщения
4,380
Реакции
0
В этой статье я расскажу, как при проведении пентеста вскрыл целый ряд уязвимостей одного веб‑сервиса, которые в итоге дали мне доступ к аккаунтам любых пользователей.

На сайте, который я тестировал, была возможность зайти в личный кабинет. А на странице входа нашлась возможность перебирать пользователей и смотреть ответ сервера: в случае если пользователь с введенным именем существует, сервер отвечает иначе.

Если указываем существующую учетку, получаем сообщение «Введен неверный пароль» либо «Превышено количество попыток входа с неверным паролем». Если же пользователя с таким логином нет, то в ответе сервера будет сообщение «Ваши данные не найдены в системе. Проверьте правильность указанных данных».
Сообщение для валидного логина




Сообщение для невалидного логина


Я запустил автоматизированный подбор по словарю и нашел некоторое количество валидных логинов.

Спреинг паролей​

  • Уровень опасности: средний
Дальше я нашел возможность подбирать по словарю пароли найденных пользователей — опять же по ответу сервера на введенные данные. Это атака password spraying. Новые пароли я пробовал каждые 30 минут, так как после каждого следующего неверного ввода учетных данных период блокировки не увеличивался. В итоге удалось подобрать пароли для трех пользователей сервиса.

Обход 2FA​

  • Уровень опасности: критический
Сразу зайти в личный кабинет не удалось из‑за того, что сервис проверял второй фактор аутентификации и просил ввести код из SMS.

Страница ввода кода из SMS


Изучив код этой страницы, я нашел интересный параметр — mode4. Здесь он имеет значение sms.

Параметры GET-запроса страницы ввода кода из SMS


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

image5_MI1sCJW.png




Интересные значения, которые может принять параметр mode4



Здесь интереснее всего значение mode4=registration, которое перенаправляет на страницу завершения регистрации в личном кабинете. Там пользователь задает себе логин и пароль, но при этом уже задал и подтвердил номер телефона.

Вид страницы при mode4=registration


Вводим и подтверждаем пароль одного из полученных ранее пользователей, и нам удается зайти в личный кабинет, минуя двухфакторную авторизацию. Также, если изменить логин на этой же странице, он сохраняется измененным.

Похищение учетки​

  • Уровень опасности: критический
Итак, мы вошли в систему без регистрации и SMS. Но на этом мы, конечно же, исследование не прекратим и продолжим копать.

Мое внимание привлекли cookie на странице смены пароля. Выяснилось, что содержимое страницы не зависит ни от каких значений, кроме UserStatus. А это значение перманентно и уникально для каждого пользователя.

Cookie UserStatus


Что будет, если подменить UserStatus одного пользователя аналогичным значением другого? Логин и пароль оставим прежними. После отправки запроса приходит ответ, что все прошло успешно. Спокойно извлекаем из него новые cookie, логин, пароль и UserToken, но уже для сессии другого юзера — того, чей UserStatus использовался. Также приходит редирект обратно на страницу входа. Если бы смена не была успешной, этим параметрам из cookie присваивались бы значения deleted и тоже происходил бы редирект.

Теперь можем войти снова — используя новые логин и пароль. Нас опять попытается остановить 2FA, то есть запрос кода из SMS. Но мы уже знаем, что делать в этом случае, и без труда проникаем в личный кабинет пользователя, UserStatus которого мы использовали.

Изменение логина и пароля пользователя



Мы не знаем UserStatus для других пользователей, но можем попробовать подобрать это значение. Его длина — 40 бит. Это 240 вариантов, то есть около 1,1 триллиона значений. Многовато для перебора!

Но если разобрать любое известное нам значение UserStatus побитово, то можно увидеть, из чего оно состоит. Половина каждого байта определяет поле, а вторая половина — значение этого поля.

Побитовый разбор значений cookie UserStatus


Теперь мы можем подбирать значения лишь 20 бит. Число вариантов сокращается до 220, то есть около 1,05 миллиона возможных значений переменной UserStatus.

Результат эксплуатации: несколько захваченных аккаунтов, потенциальная возможность захвата всех пользовательских аккаунтов за чуть более чем миллион запросов.

Выводы​

Итак, мы поняли, что есть возможность менять логины и пароли всех пользователей, UserStatus которых содержит те же поля, что известные нам. Затем мы можем пройти аутентификацию от имени этих пользователей в обход 2FA. Во время тестирования мне удалось захватить несколько аккаунтов и установить, что можно получить доступ к любой учетной записи чуть более чем за миллион запросов.

Автор @shin0_by
Источник xakep.ru
 
Сверху Снизу