В 2020 году уязвимости получения имен пользователей (username enumeration) по-прежнему широко распространены. Многие компании отказываются исправлять эти недостатки из-за страха перед негативным влиянием на прибыль и удобство пользователей. Вместо того, чтобы рассматривать примеры username enumeration, которые хорошо описаны во многих книгах и онлайн, давайте рассмотрим более эффективный и продвинутый сценарий.
С повсеместным использованием фреймворков JavaScript большая часть логики приложений была перенесена со стороны сервера (бекенд) на сторону клиента (фронтенд). Искусственный интеллект закрепляется в инструментах служб безопасности (синей команды). Все больше и больше компаний полагаются на обфускацию и готовые решения по безопасности для предотвращения эксплуатации уязвимостей, которые могли бы быть легко устранены несколькими строчками в серверной логике.
Приведенная ниже уязвимость демонстрирует опасность отказа следовать security best practice и вместо этого полагаться на сесурити ПО и обфускацию. В этом разделе мы обойдем Google SHAPE - фронтендную (на стороне клиента) схему обфускации через шифрование и фронтендную блокировку брутфорса (перебора) номеров социального страхования (SSN) жертв (американских – прим. переводчика). Также мы изучим и будем активно использовать алгоритм генерации и присваивания номеров социального страхования, информацию о смертях и социальные сети для создания полезной нагрузки (пейлоада, payload) для конкретного пользователя.
Кибербанда Юрия обратила внимание на его работу. Его схемы из предыдущих разделов принесли поток пассивного денежного дохода и номера кредитных карт для перепродажи их в даркнете. Это им приятно, но один из основных источников дохода для шайки - подача фальсифицированных налоговых деклараций с целью обмана правительства США во время налогового сезона (В США физические лица обычно должны подавать годовую налоговую декларацию до 15 апреля года, следующего за отчетным. На налоговые декларации, представленные после окончания налогового сезона, накладываются пени за просрочку платежа – прим. переводчика). Для этого банда тратит большую часть времени на получение номеров социального страхования потенциальных жертв.
Начальство банды обращается за помощью к Юрию. Они поручают ему получить как можно больше номеров социального страхования. Обычно бандиты получает номера с помощью передовых схем фишинга, социальной инженерии, телефонных звонков (вишинга) или целевых фишинговых атак на небольшие бухгалтерские фирмы и кабинеты врачей.
Юрий прежде чем приступить к поиску уязвимостей, которые можно использовать, просматривает свои заметки и предварительные исследования структуры и слабых сторон того, как социальные номера безопасности генерируются и присваиваются правительством Соединенных Штатов. Его записи содержат следующие детали:
SSN были разработаны и выпущены Администрацией социального обеспечения (SSA) в 1936 году в качестве идентификаторов для отслеживания заработка учетных лиц.
• В США до 1909 года не было подоходного налога с физических лиц.
• Назначается при рождении
• Уникален для назначаемого
Номер социального страхования имеет формат XXX-YY-ZZZZ, где:
• XXX - это номер зоны
• YY - номер группы
• ZZZZ - серийный номер
Имеются исследования по предугадыванию номеров социальной защиты SNN. Например, в 2009 году было опубликовано исследование команды Института Карнеги Меллон.
«Исследователи Университета Карнеги-Меллона доказали, что общедоступную информацию, легко получаемую из государственных источников, коммерческих баз данных или в социальных сетях в интернете, можно использовать для прогнозирования большей части, а иногда и всего девятизначного SNN (номера социального страхования) человека».
Основные моменты их выступления можно резюмировать ниже:
• Если дата рождения и место рождения цели известны, и цель родилась между 1989 и 2011 годами, то часто можно получить первые пять цифры номера SSN (и во многих случаях намного больше этого).
• В некоторых штатах в 8% случаев может быть определен весь номер SSN.
• Число можно предугадать с помощью общедоступной базы данных о смертях, опубликованной правительством США.
Изучив свои записи о номерах социального страхования, он начинает думать о потенциальных целях. Из своего опыта фишинга и мошенничества он знает, что большинство банков требуют от пользователей указывать свой номер социального страхования (SNN) при проверке запроса на сброс пароля. Поэтому он решает начать свой поиск с просмотра форм для сброса пароля в онлайн-сервисах международных банков. Он быстро находит то, что его интересует (форма сброса пароля в банке):
В отличие от форм запроса на сброс пароля в большинстве банков, для которых требуется номер учетной записи или номер кредитной карты в дополнение к SNN, этот банк требует их фамилии, номера социального страхования и даты рождения. Несколько вещей в этой форме вызывают у Юрия мурашки по спине.
Как приложение блокирует злоумышленников, которые пытаются перебрать номер социального страхования клиента? Похоже, блокировка идет по фамилии. Возможно, также они учитывают дату рождения и как-то сопоставляют фамилию с датой рождения - но даже в этом случае сотни учетных записей будут заблокированы одновременно. Например, у скольких людей с фамилией Смит одинаковые даты рождения?
Юрий предполагает, что функция блокировки, скорее всего работает на стороне клиента, чтобы предотвратить блокировку сотен пользователей. Чтобы проверить эту теорию, он отправляет запрос с выдуманной информацией и проверяет файлы cookie и локальное хранилище. (В браузере Firefox щелкните на странице правой кнопкой мыши, выберите «inspect element», «select storage», затем выберите «local storage», а затем щелкните на домен, который вы хотите проверить).
Бинго! Приложение увеличивает значение ключа «FGT_BROWSER_LOCK» на единицу каждый раз, когда отправляется запрос с информацией, которая не соответствует текущему клиенту. Дальнейшее тестирование показывает, что после пяти запросов приложение «блокирует» браузер, по-видимому, предотвращая дальнейшие запросы как показано на скриншоте ниже:
Если вручную установить для этого значения число меньше пяти (включая отрицательные числа), блокировка обходится, и можно спокойно перебирать значения (брутфорсить). Еще хуже, что поскольку большинство злоумышленников используют автоматизированные скрипты и инструменты для выполнения этих атак (например, BurpSuite или Python скрипт), таким образом значение ключа никогда не будет установлено, тем самым обходя задуманную защитную функцию.
Когда Юрий настраивает веб-браузер для использования BurpSuite и перехватывает запрос, он обнаруживает кое-что интересное. Параметры номера социального страхования (taxId) и даты рождения (dateOfBirth) шифруются до того, как они отправляются POST запросом.
Чтобы начать брутфорсить форму ему потребуется зашифровать данные номера социального обеспечения и даты рождения перед отправкой каждого запроса. Он знает, что алгоритм шифрования этих значений должна находиться на стороне клиента (он знает это потому что значение зашифровано перед отправкой в запросе).
Он просматривает исходный код веб-страниц, и кое-что действительно находится.
Страница содержит очень мало исходного кода и, похоже, загружает большую часть функциональности из одного minified файла JavaScript (all.min.js) в строке 26.
Юрий скачивает файл min.all.js на своей компьютер, и загружает его на Online JavaScript beautifier и сохраняет de-minified результаты. После беглого просмотра файла на 107 строке кода ему бросилось в глаза имя одной функции. Глобальная (global scoped) функция, называемая getEncryptor () кажется интересной.
После небольшого анализа становится ясно, что функция getEncryptor() занимается шифрованием. Далее по коду становится ясно, что приложение использует эту функцию для шифрования параметров taxId и dateOfBirth перед отправкой их в запрос.
Поскольку эти функции глобальные, не нужно никаких дальнейших изменений или реверс-инжиниринга для генерации зашифрованных значений. Если бы функции не были объявлены глобально, то можно было бы ее загрузить и отредактировать для работы на локально размещенном NodeJS или просто вырезать из файла и сделать ее глобальной. Злоумышленник может просто использовать JavaScript консоль веб-браузера, чтобы сгенерировать значения, сохранить их в офлайн режиме и импортировать в BurpSuite Intruder для выполнения атаки.
Он проверяет эту теорию, открыв веб-страницу в Firefox, щелкнув ее правой кнопкой мыши, выбирает «inspect element», а затем нажимает кнопку «console» и печатает в консоль:
Он сохраняет вывод в буфер обмена, настраивает Firefox для использования BurpSuite и перехватывает запрос со случайной датой рождения, фамилией и социальным номер безопасности (SSN) 0123456789. Он щелкает запрос правой кнопкой мыши и отправляет его в BurpSuite Repeater.
Затем он заменяет значение параметра «taxID» на значение, которое он сгенерировал в консоли, и отправляет запрос. Бум!
Приложение отвечает сообщением «User_Not_Found», указывающим на то, что зашифрованные значения были успешно расшифрованы и приняты сервером.
Чтобы проверить элементы управления блокировкой, он отправляет запрос несколько раз. После трех отправок сервер возвращает внутреннюю ошибку 500, как показано ниже в захваченном ответе:
Что происходит? По личному опыту Юрий знает, что многие банки защищены несколькими уровнями инструментов безопасности. В этом случае он делает предположение, что форма защищена Google Shape.
Авторская заметка:
Shape Defense - продукт Google (куплен компанией f5 на момент редактирования) который использует машинное обучение и искусственный интеллект. В соответствии с Shape Security | Prevent Attacks with Managed Solutions, «Shape Defense предоставляет комплексную защиту вашего сайта от ботов, поддельных пользователей и несанкционированных транзакций, предотвращая крупномасштабные мошенничества. Компании получают мониторинг, обнаружение и уход от негативных последствий, эти функции им нужны, чтобы сократить мошенничество, уменьшить затраты на облачный хостинг, пропускную способность и вычислительные мощности, а также улучшить взаимодействие с пользователем и оптимизировать свой бизнес основываясь на трафике реальных людей».
Иногда можно определить, использует ли приложение Shape, по заголовкам, отправляемым в запросе. Например, если заголовки выглядят следующим образом, это может указывать на то, что используется Shape:
X-slpF3Jx2-f:
X-slpF3Jx2-b:
X-slpF3Jx2-c:
X-slpF3Jx2-d:
X-slpF3Jx2-z:
X-slpF3Jx2-a:
Юрий выполняет быстрый поиск в Google и не находит общедоступных уязвимостей для Shape. Чтобы протестировать, защищает ли Shape форму, он открывает свой веб-браузер, открывает панель инструментов разработчика и устанавливает в локальном хранилище значение ключа FGT_BROWSER_LOCK на -99. Затем он вручную заполняет форму с поддельными данными и отправляет одни и те же фейковые данные 20 раз.
Разумеется, в ответе не возвращаются сообщения о блокировке или ошибках! Это означает, что на стороне сервера блокировка отсутствует и можно обойти Shape с помощью ручной отправки запросов, и таким образом легко обходится блокировка на стороне клиента. У него есть идея как это автоматизировать, однако сначала он просматривает свои записи о номерах социального страхования (см. выше вырезку ресерча университета Carnegie Mellon).
Он знает, что узнать дату рождения и местонахождение клиента очень просто. Кибербанда, на которую он работает, имеет миллионы записей такой информации. Для простой проверки его концепции, он решает, что самым простым способом будет изучить страницу Facebook банка и посмотреть кто комментирует страницу. Он может просмотреть профиль комментаторов в Facebook и вытащить дату рождения и местонахождение из их профиля. Следующие снимки экрана демонстрируют это:
Он замечает, что несколько миллионов человек «лайкнули» страницу банка на Facebook страница (более 4 миллионов!). Вероятно часть из этих миллионов человек – реальные клиенты.
Он нажимает на страницу и сразу видит, что люди комментируют и жалуются на проблемы с учетной записью или кредитной картой.
Выбрав одного из комментаторов и открыв его профиль видим дата и место его рождения.
Теперь, когда он нашел фамилию, дату и место рождения для одного из клиентов банка, он начинает просматривать базы данных смертей, чтобы увидеть, сможет ли он найти шаблоны, похожие на те, что были обнаружены исследователями из Карнеги-Меллона. Юрий знает, что ему нужно только угадать первые пять цифр номера социального страхования, чтобы атака стала возможной. Основную базу данных с записями о смертях (мастер-базу) можно приобрести примерно за 1000 долларов США, что определённо того стоит, учитывая, сколько денег заработает его команда в следующем налоговом сезоне.
Чтобы убедить высшее руководство шайки в том, что ему необходимо купить полную базу данных, он знает, что ему нужно показать успешный PoC (proof of concept, доказательство успешной работы концепта). Быстрый поиск в Google показывает бесплатный государственный онлайн-сервис, содержащий девять миллионов записей о смерти с датами рождения в период с 1936 по 2007 год. Хотя в нем и не содержится такое же количество записей о смертях как в мастер-базе, Юрий все равно добьется успеха.
Он переходит на веб-сайт и ищет место рождения клиента, месяц и год рождения, и смотрит сможет ли он распознать закономерность в социальных номерах безопасности, полученных из запроса.
Поисковый запрос возвращает две записи о смерти в Evanston и Oak Lawn (города около Чикаго).
Слева направо на скриншоте показаны присвоенный умершему номер социального страхования, ФИО, месяц рождения, день, год, город и штат.
Если клиент родился недалеко от этих районов (где-то в районе Большого Чикаго) между 9 и 30 апреля 1989 года, вероятно, их SSN номер между 326-84-8119 и 326-84-8638, потому что они были бы учтены в одной группе. Так как заказчик родился 28 числа апреля, вероятно, номер социального страхования ближе к 326-84-8638.
Юрий хватает своего стажера и просит его вручную набивать SNN номера, начиная с 326-84-8638 и ниже, посылая запросы вручную через веб-браузер. Пока его стажер работает, Юрий начинает придумывать план, чтобы обойти Shape, мониторинг службы безопасности и любые другие препятствия, которые могут ему помешать или предупредить специалистов по безопасности о том, что происходит атака. Он хочет придумать схему, которая продлится несколько лет и останется незамеченной, позволяя его банде загребать миллионы долларов заполняя фальсифицированные налоговые декларации и открывая мошеннические банковские счета для отмывания своих черношляпных денег.
Он решает, что следующие шаги должны помочь достичь этих целей:
- Собрать несколько разных веб-браузеров с разными версиями, шрифтами, языками и установленными плагинами.
- Собрать или купить список из тысяч HTTPS- и SOCK-проксей (легко сделать с помощью masscan или заказать у SEO-компаний на blackhatworld.com).
- Написать Python драйвер, который использует фреймворк selenium для управления браузерами из шага 1.
- Настроить браузеры на использование проксей из шага 2.
- Использовать фреймворк selenium для запуска собранных браузеров и заполнения из веб-формы, добавив задержку нажатия клавиш (как человек) и как-бы что ручного нажатия кнопки «Отправить». (Все может быть выполнено через Selenium API).
- Запустить скрипт на нескольких VPS, использующих разные ОС.
- Отправлять только один номер социального страхования для каждого браузера и прокси. Другими словами, постоянно менять собранный браузер после каждого запроса и переключать прокси. После выполнения запроса уничтожьте профиль браузера (это позволит обойти блокировку на стороне клиента).
Хотя вышеупомянутая атака, вероятно, долгое время останется незамеченной, я смог обойти Shape гораздо более простым методом. Просто используя дефолтный драйвер python selenium на Firefox и реализация слегка рандомной задержки между нажатиями клавиш при заполнении формы было достаточно чтобы обойти Shape.
Можно было бы обойти Shape даже без реализации какой-либо формы задержки, но этот метод не тестировался. Скрипт запускался на четырех Linux виртуальных машинах, использующие ту же версию драйвера браузера Firefox и тот же IP-адрес и тем не менее Shape был обойден.
Вся информация предоставлена исключительно в ознакомительных целях. Автор не несет ответственности за любой возможный вред, причиненный с использованием сведений из этой статьи.