Как я нашел баг, который раскрывал ваш пароль от PayPal

Original author: Alex Birsan
  • Translation

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

Если вы подходите к цели, как будто вы — первый человек, который оценивает безопасность, то я считаю, вы обязательно найдёте что-то новое. Особенно если код, который вы тестируете, всё ещё находится в разработке. Это история о серьёзном баге безопасности, который влияет, наверное, на самую посещаемую страницу PayPal: страницу с формой входа.


Первое открытие

Исследуя поток аутентификации в PayPal, я обратил внимание на файл javascript, который содержал то, что выглядело идентификатором сессии и токеном CSRF.

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

 В атаке, известной как XSSI, вредоносные веб-страница может воспользоваться тегом <script>, чтобы импортировать скрипт из другого источника [имеется в виду CORS], в свою очередь, позволяющий получить доступ к данным внутри атакуемого файла.

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

 Однако важность секрета измеряется ущербом, который вы можете причинить, если знаете его. Поэтому я сразу решил выяснить, что именно означают переменные _csrf и _sessionID и как их можно использовать в реальной атаке.

 После бессчётного количества попыток заменить токен CSRF аутентифицированных запросов на платформе pay pal на _csrf я пришёл к выводу, что классическая подделка запросов с этим токенами невозможна. Точно так же, чтобы выдать себя за жертву, не было достаточно идентификатора cессии из скрипта.

Затем я вернулся к уязвимому скрипту, чтобы понять, для чего он используется. Это привело меня в глубины основного механизма защиты PayPal, который применялся, чтобы предотвращать brute force — известную проблему безопасности. Хотя эта функциональность используется во многих местах, я сфокусируюсь на форме входа.

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

Когда система обнаруживает вероятный брутфорс, ответом на следующую попытку аутентификации оказывается страница, которая не содержит ничего, кроме капчи Google, и, если пользователь решил её, инициируется POST-запрос на /auth/validatecaptcha.

 В теле запроса присутствуют уже знакомые нам переменные _csrf и sessionID, а также другие значения, к которым я вернусь немного позже.

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

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

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

  • Значение jse вообще не проходило валидацию.

  • recapcha был токеном, который предоставляется Google во время решения капчи, он не привязан к определённой cессии, так что любой валидный токен, например, сгенерированный автоматическим сервисом, может подойти.

Эксплуатация

Сложив всё это вместе, я создал доказательство концепции, в котором демонстрируется весь процесс, за исключением интеграции сервиса решения капчи.

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

Как только жертва входит в PayPal с того же браузера, кэшированные случайные креды заменяются электронным адресом и паролем пользователя. Последний шаг — получить токен рекапчи, после чего креды в сыром виде отправляются серверу, к конечной точке /auth/validatecaptcha, чтобы отобразиться на странице.

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

Раскрытие информации

Доказательство концепции вместе с соответствующей информацией были отправлены в программу Bug Bounty от PayPal 18 ноября 2019 года и проверены на HackerOne спустя 18 дней. Затем последовало быстрое подтверждение от команды PayPal и несколько дополнительных вопросов. Моё вознаграждение составило $ 15300, я получил его 10 декабря. Да, баг получил оценку 8 баллов (высокий приоритет) по шкале CVSS — эту же оценку поставил я, когда отправлял свой отчёт.

Патч применили спустя ещё 24 часа. Это означает, что ошибку исправили через 5 дней после предупреждения — это довольно впечатляющий срок.

Исправление и рекомендация по профилактике

Конечная точка /auth/validatecaptch теперь требует дополнительного токена CSRF, который не может быть скомпрометирован при помощи включения межсайтового скриптинга.

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

Даже крупные компании совершают порой ошибки и допускают уязвимости. На нашем курсе «Этичный хакер» мы учим студентов искать эти уязвимости и зарабатывать на этом. Если устали чинить баги в коде и постоянно надстраивать что-то новое — приходите к нам, будем учиться «ломать», находя бреши в софте даже у крутых корпораций.

Узнайте, как прокачаться в других специальностях или освоить их с нуля:

Другие профессии и курсы
SkillFactory
Школа Computer Science. Скидка 10% по коду HABR

Comments 2

    +1

    "Paypal, карты, безопасность" говорили они… На их месте я бы давно хешировал пароль ещё в браузере, и в пересылках использовал только хэш, и лучше каждый раз с рандомной солью, чтобы при всем желании криворукого разработчика не мочь его нигде засветить, если вдруг кто-то захочет возвращать пароль для автозаполнения формы.

      0

      Не холивара ради, а для саморазвития хочу спросить: а в чем разница между отправкой пароля в открытом виде и отправкой хэша с клиента? Если сервер даёт доступ по этому хэша? А если рандомная соль генерируется на клиенте, то, как сервер проверит этот хэш? Если же позиция и длина истиной части ключа известны, то что мешает тогда злоумышленнику также разобраться и самому подставлять рандомную соль?

    Only users with full accounts can post comments. Log in, please.