Разбивка скиммера Anti-VM и его вариантов от самой ранней версии до последней версии, предоставленной staticcounter.]net.

После твита @rootprivivе о скиммере, обслуживаемом недавно зарегистрированным (2022–05–11) staticcounter.]net, я решил присмотреться. Я начну с описания моего процесса деобфускации, но если вас больше интересует работа настоящего скиммера, вы можете пропустить его.

Распаковка деобфускации

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

@AffableKraut любезно поделился кодом скиммера, который был вставлен в конце скрипта. Я обрезал его до сам скиммер.

Вот сокращенная версия:

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

Структура обфускации довольно проста:

  1. Объявление многих переменных в глобальной области видимости.
  2. Анонимный IIFE, содержащий:
    1. Объявление функции — UDS. Он заканчивается на .join, и я вижу, что есть пара вызовов с неразборчивыми строками в качестве аргументов, что наводит меня на мысль, что функция является декодером.
    2. Присвоение свойства функции UDS в новую переменную — AET. Затем эта переменная используется как функция парой строк ниже.
    3. Объявляется переменная BTX и строкой позже она используется как функция.
    4. Наконец, почти в конце script переменная Uku — еще одна ссылка на AET — вызывается для создания функции CuM, которая затем выполняется. Поскольку выполнение функции CuM не сохраняет вывод ни в какую переменную, я предполагаю, что это основная функция скиммера.

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

Упаковщик

Почему я думаю, что функция UDS является декодером? Давайте рассмотрим это:

Даже не глядя на то, как работает функция UDS, мы можем сказать, что она возвращает строку, так как substr связана с ней. Запуск функции с запутанной строкой в ​​качестве входных данных дает строку constructorabcdefghijklmnopqrstuvwxyz. Я рискну предположить и скажу, что MXQ равно 11, что оставит нам только слово constructor. Это отвечает на вопрос о том, как создаются функции BTX и CuM: с помощью метода конструктора функции UDS.

Еще пара объявлений и замен, и мы получим вторую функцию декодера в BTX:

Следующая строка присваивает FpP значение двух функций декодера в строке:

var FpP = BTX(UDS(‘ih)c 2pni:%#DD5rn,|p26tca 0…..’));

Что оставит его с кодом функции, созданной в следующей строке.

Складывая все это вместе, мы получаем:

Это был поток упаковщика, который строит фактический код скиммера. Чтобы извлечь сам скиммер, просто посмотрите на значение переменной FpP. Чтобы получить красивую распечатку кода, замените выполнение функции CuM на

console.log(CuM.toString());

Запутанный скиммер

Просто просмотрев код (каламбур), вы можете сказать, что основной трюк запутывания здесь — это ссылки на замену массива, поскольку существует много — чуть меньше 600 — ссылок на разные индексы переменной _0x26713. Вот пример:

Когда я искал объявление переменной, я обнаружил, что ей присвоен результат вызова функции с длинной бессмысленной строкой в ​​качестве единственного аргумента. Звучит знакомо?

var _0x26713 = (_0x270ED)(“fisctlue-rtrornx.=oadan…”);

Да, это еще один декодер, который широко используется скиммерами, которые я исследовал. Вы можете идентифицировать его по структуре join-split-join-split:

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

i71.cd.nb = dN34.getElementById(‘number’).value;

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

(Не очень) Anti-VM Skimmer

В той же ветке Twitter Malwarebytes указали, что этот скиммер связан со скиммером анти-ВМ. Сравнение кода обоих скиммеров подтверждает это, хотя в новом образце была снята проверка анти-ВМ ¯\_(ツ)_/¯. Примерно через неделю Malwarebytes опубликовала сообщение в блоге, описывающее широту инфраструктуры, обслуживающую варианты одного и того же скиммера.

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

Изучив несколько образцов, как из вредоносных доменов, которые они упомянули в своем посте, так и из других, которые я нашел (таких как staticcounter.]com, зарегистрированных с 2020–12–19 гг.), Похоже, что кампания нацелена на широкий спектр платежных систем, где каждый скиммер подбирает свои методы для целевой платформы и поставщика платежных услуг.

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

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

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

Обход платежного iframe Stripe

Последний вариант, предоставленный staticcounter.]net, предназначен для Magento версии 1. Он использует функцию VarienForm, которая устарела в Magento 2, наряду с платежной формой Stripe, очевидно. полагаясь на существование таких элементов на странице, как #stripe-payments-card-number и #payment_method_stripe.

Как только подтверждается наличие упомянутых выше элементов на странице, начинается атака:

  1. Скрытие iframe песочницы реальной платежной формы и внедрение собственного доступного iframe.
  2. Замена настоящей кнопки отправки на поддельную.
    Это предотвращает отправку формы сайтом, когда пользователь нажимает кнопку, и позволяет злоумышленнику запуститься первым, не соревнуясь с какой-либо оригинальной функциональностью сайта, которая может активироваться на тот самый щелчок.
  3. Внедрение поддельной платежной формы в новый iframe, что позволяет скиммеру отслеживать вводимые данные, делая их похожими на исходную форму, в комплекте с проверкой действительности и значком бренда кредитной карты, который соответствует типу введенного номера карты.
  4. После того, как детали платежа введены полностью, скиммер собирает всю доступную личную информацию (PII), которую ему удается найти, считывая значения из определенных полей в форме оформления заказа, таких как #billing[firstname], #billing[lastname], #billing[email] и #address.
  5. Собрав всю платежную информацию и PII, он шифрует данные и отправляет их обратно на свой сервер с помощью запроса JQuery Ajax POST.
  6. Последний шаг включает в себя удаление поддельного iframe и восстановление оригинала, а также нажатие исходной кнопки отправки, чтобы получить сообщение об ошибке по умолчанию, касающееся неполного номера кредитной карты, поскольку настоящие поля ввода оставались пустыми.

Скиммер использует создание файлов cookie, чтобы отслеживать, была ли атака активирована (имя файла cookie form_key_id) или завершена (имя файла cookie _gld). Это позволяет ему избежать избыточной повторной инъекции или нападения на жертву более одного раза, что может привести к ее раннему обнаружению.

Скрывая исходный iframe платежа и внедряя свой собственный, скиммер обходит защиту, которую обеспечивает iframe. Это также означает, что сайт может больше не соответствовать требованиям PCI, что может привести к большим штрафам и снижению репутации.

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

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

Правдами и неправдами

Самый ранний образец, который я видел, датированный июнем 2021 года, нацелен на Magento 2 с использованием той же техники «приманки и подмены», заключающейся в внедрении другого iframe с поддельной формой. Мы можем определить это, сравнив его целевые селекторы CSS с исходным кодом Magento. Вот пара примеров: старый скиммер искал #stripe-card-element, а новый ищет #stripe-payments-card-number. Старый скиммер искал checkout в URL вместо firecheckout. И использование класса populated при сообщении об ошибках номера кредитной карты существовало в версии 1, но было удалено в версии 2. Еще одно небольшое, но интересное отличие заключается в том, что более новая версия не собирает пароли, что делала старая, извлекая значение из поле #billing:customer_password.

Другие варианты нацелены на большее количество поставщиков и платформ платежей, таких как USA ePay от NMI, модуль авторизации CIM Payment от Magento, PayPal DPM, InstaSend, Adobe Commerce и eWay, и это лишь некоторые из них.

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

alert(‘Gateway error. You will be automatically redirected to the our website for payment processing after placing the order.’);

Вместо того, чтобы использовать файл cookie, чтобы пометить атаку как завершенную, или фальшивую форму как внедренную, скиммер может использовать ключи localStorage, такие как mage-cache-version или recently_viewed_product_session, как показано в этом варианте.

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

Краткое содержание

Атаки Magecart, будучи более «скрытыми», наряду с названиями скиммеров, такими как «анти-VM», представляют собой изменение не самих атак, а их поддерживающей инфраструктуры; Эти механизмы уклонения призваны помешать нам — исследователям и защитникам — обнаружить и остановить атаки до того, как они начнутся. Требуя взаимодействия со страницей, запрашивая действительный заголовок referer или проверяя, что IP-адрес не принадлежит известной службе VPN, злоумышленники пытаются повысить вероятность того, что мы пропустим их скиммер с помощью нашего автоматического сканирования.

Скиммер для защиты от виртуальных машин подчеркивает необходимость защитных решений, которые работают в сеансе и могут обнаруживать атаки цифрового скимминга, не полагаясь на внешнее сканирование или сканирование в песочнице. PerimeterX Code Defender — это такое решение, которое дает вам представление о том, какой код выполняется на вашем сайте, независимо от того, является ли он собственным или сторонним, статическим или динамически загружаемым. Решение предоставляет оповещения при возникновении таких атак и возможность блокировать выполнение нежелательных действий любым скриптом.