В охоте на проблемы безопасности погоня за неизведанными активами и скрытыми конечными точками часто заканчивается тем, что вы отвлекаетесь от очевидной, но по-прежнему важной функциональности. Если вы подходите к цели, как будто вы — первый человек, который оценивает безопасность, то вы обязательно найдёте что-то новое. Особенно если код, который вы тестируете, всё ещё находится в разработке. Специально к старту нового потока курса «Этичный хакер», делимся с вами историей о серьёзном баге безопасности, который влияет, наверное, на самую посещаемую страницу 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, который не может быть скомпрометирован при помощи включения межсайтового скриптинга. Такой подход действительно исправляет уязвимость, но я считаю, что этого можно было бы избежать, если бы в дизайне системы следовали старейшему и важнейшему совету в информационной безопасности: никогда не храните пароли в виде простого текста. Даже крупные компании совершают порой ошибки и допускают уязвимости. На нашем курсе «Этичный хакер» мы учим студентов искать эти уязвимости и зарабатывать на этом. Если устали чинить баги в коде и постоянно надстраивать что-то новое — приходите к нам, будем учиться «ломать», находя бреши в софте даже у крутых корпораций. Узнайте, как прокачаться в других специальностях или освоить их с нуля: Профессия Data Scientist Профессия Data Analyst Курс по Data Engineering ПРОФЕССИИ Профессия Fullstack-разработчик на Python Профессия Java-разработчик Профессия QA-инженер на JAVA Профессия Frontend-разработчик Профессия Этичный хакер Профессия C++ разработчик Профессия Разработчик игр на Unity Профессия Веб-разработчик Профессия iOS-разработчик с нуля Профессия Android-разработчик с нуля КУРСЫ Курс по Machine Learning Курс "Machine Learning и Deep Learning" Курс "Математика для Data Science" Курс "Математика и Machine Learning для Data Science"  Курс "Python для веб-разработки" Курс "Алгоритмы и структуры данных" Курс по аналитике данных Курс по DevOps редактор, автор, солдат удачи