- Um desenvolvedor no Canadá foi alvo de um ataque para induzir a instalação de um backdoor disfarçado de falsa entrevista com VC, e o fluxo do ataque era tão alinhado ao trabalho de desenvolvedores que levantou suspeitas de mirar o gerenciador de pacotes crates.io
- O repositório-isca parecia um app TypeScript chamado “Ticket Harbor”, mas escondia código malicioso no caminho de execução do TypeScript usando
patch-packageetypescript+5.9.2.patch - O stub inserido desfazia a ofuscação em base64 e XOR, executava via
new Function(...)e, passando por um chunk oculto emoperators/3.pnge um stub WASM, iniciava um payload de segunda etapa de 1,68 MB em um processo Node separado - O payload final, “PinpinRAT”, criava um par de chaves RSA-2048 e uma chave de sessão AES-256-CBC, e oferecia coleta de fingerprint do host, upload e download de arquivos, execução de processos, manipulação do sistema de arquivos, consultas DNS e autorremoção
- Se você executou o repositório, deve desconectar a rede imediatamente e trocar credenciais a partir de outro dispositivo, partindo do pressuposto de que cookies e segredos protegidos por senha também podem ter sido roubados
Ataque direcionado a desenvolvedor começou com entrevista falsa
- O atacante fez contato se passando por uma pessoa ligada à “Lua Ventures”
- A Lua Ventures foi apresentada como uma VC do setor de DeFi sediada em Singapura, mas na prática já havia encerrado suas atividades
- O nome da pessoa não foi divulgado porque poderia ser confundido com homônimos reais
- O e-mail era convincente e incluía um link para um perfil do LinkedIn comum, mas aparentemente legítimo
- Como empresas de investimento em busca de consultoria, mencionava Lyrasing e Roadpay
- As duas empresas tinham uma presença básica na web, parecendo mais startups em estágio inicial do que entidades falsas
- Também existe um snapshot no archive.org do site da Roadpay
- Após uma troca de e-mails, houve até uma chamada no Google Meet
- A pessoa na chamada era um homem com sotaque alemão, que disse estar em deslocamento
- A chamada em si não teve nada claramente estranho
Gatilho de execução disfarçado de “tarefa de teste”
- Depois da chamada, o atacante propôs um “teste” e enviou um repositório
- O repositório foi apresentado como um app de bilhetagem de balsas chamado “Ticket Harbor”
- O
task.txtincluído continha uma lista de tarefas entediante, mas plausível, e no final trazia instruções de execução- Pedia para executar o typecheck do repositório, a suíte de testes e comandos relacionados de build desktop/server
- Essas instruções eram o gatilho real da infecção
- No momento em que o TypeScript fosse executado por comandos como
npm run typecheck,buildoudev, ou quandotypescript.jsfosse importado, o payload poderia ser executado
- No momento em que o TypeScript fosse executado por comandos como
Cadeia de execução escondida em um patch do TypeScript
- O primeiro sinal de alerta foi o repositório parecer uma tarefa de TypeScript
- O pedido se aproximava mais de um teste de contratação em TypeScript do que de uma análise de arquitetura
- Ao colocar o repositório no Claude para uma verificação rápida, surgiram indícios anômalos relacionados ao
patch-package
- O diretório
patches/era incomumente grande- Alguns patches pareciam legítimos e serviam como ruído para esconder o payload real
- Exemplos incluíam
sumchecker+3.0.1.patch,@electron+get+2.0.3.patcheextract-zip+2.0.1.patch
- O código malicioso principal estava em
typescript+5.9.2.patch- Ele inseria um stub de execução imediata no topo de
typescript.jse_tsc.js - O stub decodificava uma string base64, descriptografava cada byte com XOR usando a chave
73e executava o resultado comnew Function(...) require,Buffer,WebAssembly,processe__dirnameeram passados para a função executada
- Ele inseria um stub de execução imediata no topo de
- A cadeia de execução passava por várias etapas
- Quatro hooks
postinstallexecutavampatch-package - Um deles aplicava
git update-index --skip-worktreeao arquivo de patch para escondê-lo dogit status - O loader lia um chunk oculto anexado ao arquivo
operators/3.png - Executava um pequeno stub WASM de um chunk
wAsmpersonalizado - Executava um payload de segunda etapa ofuscado de 1,68 MB em um processo Node separado e silencioso
- Quatro hooks
- O código de ataque foi projetado para reduzir vestígios após a execução
- Escondia o patch com
git skip-worktree - Depois da primeira execução, o dropper apagava do arquivo de patch as linhas que havia inserido
- O diretório temporário da segunda etapa se autoexcluía durante a execução
- Escondia o patch com
Funcionalidades do PinpinRAT
- O payload final é chamado de “PinpinRAT”
- O nome vem de strings internas, e não se descarta que seja conhecido por outro nome
- Nenhuma outra referência online foi confirmada
- O payload estava dentro de várias camadas de ofuscação
- obfuscator.io
- Duas camadas adicionais de base64
- Ao iniciar, o RAT coletava e exfiltrava o fingerprint do host
- Endereço IP principal e lista completa de IPs
- Nome de usuário de
os.userInfo().username - Nome do host
- Tipo, release, plataforma e arquitetura do SO
- PID do processo e
process.argvcompleto - Versão do Node
- Também incluía uma estrutura de criptografia
- Geração local de par de chaves RSA-2048
- Geração de uma chave de sessão AES-256 aleatória
aes_psk - O tráfego subsequente era criptografado com AES-256-CBC e acompanhado de uma tag de integridade HMAC-SHA256
- Os comandos suportados ofereciam funcionalidades no nível de um trojan de acesso remoto
env: transformaprocess.envem uma string JSON e a enviaupload: lê e exfiltra um caminho de arquivo arbitráriodownload: grava bytes fornecidos pelo atacante em um caminho gravávelspawn: executa um processo arbitrário com expansão opcional via shellls,cd,pwd,cp,mv: manipulação comum do sistema de arquivosdns: resolve nomes arbitrários por meio de um resolver especificadodismantle: autorremoção
Indicadores de comprometimento e resposta imediata
- A imagem que continha o payload não foi detectada por nenhum mecanismo de AV no VirusTotal
- Se foi executado, o sistema deve ser isolado da rede imediatamente
- As credenciais devem ser trocadas a partir de outro dispositivo
- Cookies e segredos protegidos por senha também devem ser considerados comprometidos
- Os indicadores de comprometimento relacionados ao PinpinRAT são os seguintes
- C2:
89.124.107.161:80 - Tarefa agendada no Windows:
PinpinWrappedJs - Disfarce de processo no macOS:
com.apple.WebKit.Networking - Variáveis de ambiente:
NODT_PAYLOAD_PATH,NODT_PAYLOAD_ARGS - Guard do chunk PNG:
WASMPACK(wAsm) PINPIN_NO_AUTOSTART=1: interrompe persistence- cronjob contendo
mutex.js: pode existir apenas quando há permissões do RAT, e pode não existir no macOS - Strings âncora em
typescript.js:12ff4b51,ticket-harbor-tsc-shim-anchor typescript+5.9.2.patchcontendo o payload- Diretórios de artefatos:
- macOS:
~/Library/Caches/runtime-cache/.cache-<randomhex>/ - Linux:
/tmp/.cache-<randomhex>/ - Windows:
%TEMP%\.cache-<randomhex>\ - Contêm
payload.jsemutex.js
- macOS:
- C2:
Sinais de alerta vistos tarde demais
- As mensagens continham expressões que, em uma leitura mais cuidadosa, pareciam marcas de LLM
- O perfil do LinkedIn parecia normal à primeira vista, mas a listagem de diplomas e certificações era estranha e não havia atividade real
- Os links de redes sociais no site tinham histórico real, mas o nome foi alterado em novembro de 2025
- As publicações tinham pouca especificidade e pareciam elogios vagos às empresas
- Os sites das empresas eram vistosos, mas quase não havia presença real
- O atacante não enviou um convite formal de calendário; apenas informou o horário e o Google Meet
- Durante a chamada, a câmera permaneceu desligada o tempo todo, e a pessoa disse estar em deslocamento
- Uma VC sediada em Singapura, atividade no fuso CEST, abordagem a um desenvolvedor canadense e domínios
.ccvoltados a clientes dos EUA apareceram juntos- Era mais difícil verificar a credibilidade de uma organização distante
- Cada sinal isolado não era conclusivo, mas vários alertas amarelos acumulados formavam um padrão que podia ser visto como alerta vermelho
Autoria e escopo do ataque
- Não é possível confirmar quem está por trás
- O ataque mirava desenvolvedores e incluía persona falsa, uma história de cobertura convincente, vários sites falsos, uma agenda paciente e uma armadilha sofisticada com
git - Ele se alinha ao fluxo de “golpe de entrevista falsa” usado por vários agentes em 2026
- Na comunidade Rust do Reddit, também foi mencionado um caso de alvo semelhante
- O ataque era tão próximo do fluxo de trabalho de desenvolvedores que, se tivesse sido estruturado em um repositório Rust com um script-armadilha
build.rs, poderia ter enganado a vítima
1 comentários
Comentários no Lobste.rs
Achei confuso o título especular que poderia ser um agente patrocinado por Estado. Não há nada aqui que pareça necessariamente exigir esse nível de preparação ou complexidade
Dá para imaginar essa possibilidade, mas ela parece tão plausível quanto outros cenários
Ainda assim, quase certamente não acho que seja um agente patrocinado por Estado. Ataques desse tipo já não são tão difíceis
É realmente uma coincidência que este ataque se pareça com o caso hipotético que descrevi no meu post da semana passada: the hypothetical I describe in my blog post from a week ago
Eu só escolhi um entre alguns ataques plausíveis como exemplo de algo que até profissionais com bom conhecimento técnico poderiam cair. Tenho visto um aumento de vários golpes sofisticados voltados a pessoas, mas não sabia que havia uma tendência em andamento de golpes de entrevista. Por isso, ao saber deste ataque, fiquei meio arrepiado
Na semana passada, recebi de D____ S_____ da Lua Ventures uma proposta de entrevista exatamente nesse estilo. Ignorei como faço com a maioria dos spams de recrutadores, e ainda bem que fiz isso
Acho que houve uma submissão assim alguns dias ou semanas atrás
Tive a impressão de que havia vários textos parecidos
Acho surpreendente dizerem que “parecia um e-mail real”. Para mim era tão obviamente uma frase gerada por LLM que eu teria desconfiado já na segunda frase