O notebook era a porta de entrada
A Binance diz que o maior roubo de criptomoedas já registrado, cerca de US$ 6,3 bilhões, pode ter começado no notebook comprometido de um engenheiro de DevOps. O grupo apontado como responsável tem um hábito: fazer um desenvolvedor executar um projeto e depois usar tudo o que o notebook alcança. Agentes de código agora executam projetos o dia inteiro. No Bromure Agentic Coding, esse código roda em uma VM que guarda credenciais substitutas, e todo uso de uma chave de produção passa pelo Mac.
O atacante não precisava das chaves privadas da Binance. Precisava do notebook de um engenheiro e dos sistemas que ele alcançava. A máquina de um desenvolvedor é um caminho até a produção, e os agentes de código agora executam qualquer código que chegue a ela.
Em 30 de outubro, a Binance divulgou um “incidente de segurança” envolvendo cerca de US$ 6,3 bilhões em ativos. O The Hacker News informa que a Chainalysis estimou o roubo em US$ 5,912 bilhões no momento em que aconteceu, quase quatro vezes o maior roubo de criptomoedas registrado até então. Quase US$ 3 bilhões foram congelados on-chain, a maior parte em stablecoins congeladas pela Tether e pela Circle. A Binance diz que vai cobrir todas as perdas.
O relato da Binance sobre como tudo começou cabe em uma frase. “A investigação inicial sugere que o incidente de segurança pode envolver o notebook comprometido de um engenheiro de DevOps”, o que permitiu a um atacante alcançar um contêiner de serviço e enviar saques não autorizados. A Binance diz não ter encontrado indícios de vazamento de nenhuma chave privada de carteira. Ela não disse como o notebook foi comprometido.
Cinquenta assinaturas e três minutos
O registro on-chain mostra quanto valia esse acesso. Às 20h20 UTC, o atacante enviou uma transação com 50 autorizações, cada uma assinada pela hot wallet da Binance, uma para cada um de 50 números de transação consecutivos, para que uma delas coincidisse com o próximo da carteira. Cada uma apontava para um contrato de varredura que só aceita ordens do atacante. Uma coincidiu. Cerca de três minutos e 24 segundos depois, a hot wallet enviou todo o seu saldo ao atacante: 167.464 ETH e 63 tokens, entre eles 1,615 bilhão de USDT.
O CEO da Blockaid, Ido Ben-Natan, disse ao Cointelegraph que as primeiras evidências apontam para “uso indevido de chave”: o sistema de assinatura foi levado a assinar as transações do atacante, e nenhuma chave precisou ser roubada. As chaves ficaram onde estavam. Alguém com o acesso do engenheiro pediu ao sistema que as usasse.
A TRM Labs atribui o ataque “com alta confiança” ao TraderTraitor, o grupo norte-coreano que o FBI responsabilizou pelo roubo de US$ 1,5 bilhão da Bybit em fevereiro de 2025. A Chainalysis também aponta para a Coreia do Norte. A Binance não nomeou ninguém.
Como esse grupo chega aos notebooks
A invasão mais bem documentada do TraderTraitor mostra o método. No caso Bybit, o próprio relatório preliminar da Safe e as conclusões da Mandiant o descrevem em ordem:
- Em 4 de fevereiro de 2025, um desenvolvedor da Safe executou no
seu Mac um projeto Docker chamado
MC-Based-Stock-Invest-Simulator-main. A Mandiant acredita que o desenvolvedor foi convencido a fazer isso. - O projeto se conectou a
getstockprice[.]com, um domínio registrado dois dias antes, e a estação de trabalho macOS do desenvolvedor foi comprometida. - Os atacantes pegaram os tokens de sessão da AWS do desenvolvedor, o que lhes permitiu usar o acesso dele à AWS sem passar pela autenticação multifator.
- Com esse acesso, alteraram a interface da Safe usada pelos signatários da Bybit, e os signatários aprovaram uma transação que esvaziou uma cold wallet.
A Mandiant observou que o grupo já tinha usado projetos Docker parecidos, com
tema de bolsa de valores, em roubos anteriores. O método não muda: dar um
projeto a um desenvolvedor, deixá-lo rodar como ele e levar o que a máquina
dele alcança. Um notebook de DevOps alcança muita coisa. Em geral ele guarda
~/.aws com tokens de sessão válidos, um ~/.kube/config para clusters de
produção, chaves SSH para o bastion e um login do gh, tudo legível por
qualquer processo que o engenheiro inicie.
Agora quem executa o projeto é o agente
A isca antes dependia de um desenvolvedor que pudesse ser convencido a
executar algo. Esse passo está ficando mais fácil de pular. No mesmo dia em
que a Binance divulgou a invasão, o
BleepingComputer
noticiou a análise da Air Security de um repositório do GitHub chamado
SolanaUpdateTools/solana-starter-kit. Ele tem 286 estrelas e, segundo a
Air, aparece em primeiro lugar quando agentes de código com IA procuram um
starter kit de Solana. O README é o único arquivo do repositório. Ele promete
um template de aplicativo completo e dá um único passo de instalação: colar um
comando que monta, a partir de fragmentos, uma URL em developer-update[.]app,
baixa um script e o executa na memória.
O payload que a Air recuperou instala o NetSupport Manager, uma ferramenta legítima de acesso remoto, configurada para se conectar ao atacante a cada login. Em seguida, exibe um erro falso: as funções de desenvolvedor estão “temporariamente pausadas devido à carga”, tente de novo em 72 horas. Um agente que seguisse o README executaria o comando e relataria um servidor ocupado. O desenvolvedor não veria nada que merecesse uma segunda olhada.
Coloque esse agente no notebook de um engenheiro de DevOps, com o kubeconfig e a sessão da AWS do engenheiro no mesmo diretório pessoal, e o starter kit vira o projeto Docker do caso Bybit, sem a engenharia social.
O mesmo projeto no Bromure Agentic Coding
O Bromure Agentic Coding roda Claude Code, Codex, Grok, Kimi e omp em VMs Ubuntu no seu Mac. Cada máquina é uma VM própria, e tudo o que o agente toca fica dentro dela: repositórios clonados, caches de pacotes, contêineres Docker e cada comando que um README sugere. O seu Mac guarda as credenciais reais, o proxy por onde passa o tráfego da VM e o registro do que aconteceu.
O projeto roda na VM, não como você
Execute o projeto Docker do simulador de bolsa em uma máquina do Bromure, ou
deixe o agente colar o comando do starter kit. O contêiner inicia na VM, e o
payload também. Ele ganha um shell em um convidado Ubuntu, como o usuário da
máquina. Não ganha sua conta do macOS nem seu Keychain. Os ~/.aws, ~/.kube
e ~/.ssh do seu Mac também não estão lá: o Bromure lê esses arquivos no host
quando você os importa e nunca os monta em uma VM.
As chaves que ele encontra são substitutas
Em seguida, o payload procura credenciais, e a VM tem muitas que parecem certas. Nenhuma funciona em outro lugar.
- AWS.
~/.aws/configaponta para um auxiliar que entrega o ID real da chave de acesso com uma chave secreta falsa, e nenhum token de sessão. A VM assina cada requisição com o segredo falso, e o Mac a assina de novo com o real a caminho de*.amazonaws.com. Copie as credenciais da AWS da VM para outra máquina e toda chamada falha comInvalidSignatureException. O token de sessão que os atacantes da Bybit levaram não existe na VM de forma nenhuma. - Kubernetes. O
~/.kube/configda VM é sintético. Okubectlfala com o proxy do Bromure, nunca direto com o servidor de API. Um bearer token é um substitutobrm-k8s-…, um certificado de cliente é descartável, e um plugin exec comoaws eks get-tokenroda no Mac em vez de na VM. - SSH. O
SSH_AUTH_SOCKda VM é uma ponte para o Mac. O convidado pode pedir uma assinatura, e a chave privada nunca sai do host.ls ~/.ssh/id_*não encontra nada para copiar. O ssh-agent do seu próprio Mac nunca é exposto a uma VM. - Git. O token do GitHub no
ghe em~/.git-credentialsé um substituto que o proxy troca pelo real só em requisições para github.com.
Os substitutos também servem de armadilha. Se o payload enviar um deles para o próprio servidor, o proxy bloqueia a requisição com HTTP 451 antes que um byte saia do seu Mac, pausa a VM e mostra This environment may have been compromised, indicando a credencial e o host para onde ela ia. A máquina não volta a iniciar até que seu disco e seu diretório pessoal sejam apagados. Suas configurações e chaves são mantidas.
As chaves de produção respondem a você
Os substitutos resolvem o roubo. O caso Binance acrescenta um segundo risco: um atacante que nem rouba o acesso e o usa de onde ele já funciona. Um payload dentro da VM pode enviar requisições pelo proxy como o agente faz. Os Guardrails do Bromure decidem o que essas requisições podem fazer, e são aplicados no Mac, onde nada na VM pode alterá-los.
- Require approval to use, definido por credencial: na primeira vez que um contexto do Kubernetes, uma chave da AWS ou uma chave SSH é usado em uma sessão, o proxy segura a requisição e pergunta no seu Mac. Você escolhe 5 minutos, uma hora ou a sessão, ou Don't allow. Na AWS, a verificação cobre cada chamada de assinatura. Um payload que tenta alcançar o cluster de produção antes da sua aprovação coloca uma caixa de diálogo na sua tela, e não recebe nada até que alguém responda.
- Política de escrita, definida por serviço. Máquinas novas começam em Prompt before write para Kubernetes, AWS, registros de contêineres, forjas git e bancos de dados: leituras passam, e cada escrita para em uma caixa de diálogo que mostra a operação exata. Block destructive recusa exclusões e encerramentos, e Read-only recusa qualquer alteração. Uma máquina que só precisa ler logs da produção pode ficar em somente leitura, e nada que rode nela consegue alterar a produção.
- Outbound connections, o firewall de cada máquina. Defina Unmatched
traffic como Deny e permita só os hosts de que o projeto precisa. O
download do starter kit em
developer-update[.]app, a chamada do projeto da Bybit agetstockprice[.]come a conexão de volta do NetSupport caem todos na regra padrão e são recusados.
Todo uso de credencial, assinatura, bloqueio e permissão vai para a Security Timeline da máquina, com chamadas de assinatura da AWS e assinaturas SSH registradas uma a uma. A Binance agora está reconstruindo um caminho de ataque por meio de um “computador comprometido”. No Bromure, o registro do que a VM fez com suas credenciais fica no Mac, fora da VM que o atacante controlava.
Mantenha o starter kit longe da produção
Máquinas do Bromure são baratas de criar, então o acesso pode ser dividido
entre elas. As credenciais são configuradas por máquina. Não dê nenhuma
credencial de produção, e dê um firewall que nega por padrão, à máquina que
testa um starter kit novo, um teste técnico para fazer em casa ou o
repositório de um desconhecido. Deixe o kubeconfig e o papel da AWS na máquina
que faz o trabalho de implantação, com aprovação exigida para cada um. Para
algo que você prefere não guardar, bromure-cli vm run --rm cria uma máquina
que é apagada quando para.
O payload pode então dominar a VM do starter kit e não encontrar nada que valha a pena: nenhum segredo real, nenhum cluster e nenhuma rota até um host que você não permitiu. A máquina de implantação nunca executou o código dele.
O projeto roda em uma VM
Projetos Docker, comandos de README e as instalações do agente rodam na VM Ubuntu da máquina, longe da sua conta do macOS e do seu Keychain.
Substitutos, não tokens de sessão
Os segredos da AWS são falsos e os tokens de sessão não existem, os kubeconfigs são sintéticos, as chaves SSH ficam no Mac. Cópias falham em qualquer outro lugar.
A produção pergunta antes
A aprovação por credencial e as políticas de escrita por serviço rodam no proxy do seu Mac. Nada na VM consegue desligá-las.
Negue o host desconhecido
Com Unmatched traffic em Deny, o download de um payload e a conexão de volta dele são recusados, e a tentativa fica registrada.
Veja acontecer duas vezes
Nossa série de tutoriais A Tale of Two Agents é inspirada neste ataque. Theo, engenheiro de DevOps na Coinvance, uma exchange fictícia, pede ao agente de código que termine o teste técnico de um recrutador, e o README manda o agente rodar primeiro um script de instalação. O mesmo erro acontece duas vezes em tela dividida: à esquerda, o agente roda no notebook dele; à direita, no Bromure.
- O teste técnico (1:24). No notebook, o script manda as chaves de nuvem reais dele, o kubeconfig e o token de deploy como “telemetria”. No Bromure, só encontra substitutos, e quando eles seguem para o host errado, o Bromure pausa a VM e pergunta a ele.
- Movimento lateral (1:18). Alguém altera o serviço de saques com o acesso de Theo ao Kubernetes. À direita, a Security Timeline rastreia a requisição bloqueada até o raciocínio do agente, e o workspace é apagado com um clique.
- Vinte minutos (1:02). À esquerda, as hot wallets se esvaziam. À direita, não há chaves para trocar.
Theo e a Coinvance são inventados, e os episódios não retratam o que aconteceu na Binance. Cada um é narrado em oito idiomas.
A máquina do desenvolvedor faz parte da produção
O serviço de saques da Binance está fora do ar para uma “reformulação de segurança” e deve voltar em até 48 horas, e a análise completa dirá mais sobre como o notebook foi alcançado. A Bybit já ensinou o padrão a todo mundo. Atacantes que querem os sistemas de produção de uma empresa vão atrás das máquinas dos engenheiros que os operam, e na maioria dessas máquinas o acesso à produção está em alguns arquivos do diretório pessoal.
O seu agente de código amplia essa abertura. Ele clona, instala e executa código de desconhecidos tarefa após tarefa, e cola o comando de um README mais rápido do que você. No Bromure Agentic Coding, o código roda em uma VM que só guarda substitutos, e o acesso à produção fica no Mac, atrás de uma caixa de diálogo que você precisa responder.
Para uma campanha de roubo de tokens que não precisou de nenhum servidor do atacante, leia O token roubado não precisava de servidor. Para um agente que recebeu ordens de um arquivo baixado, leia O download dava as ordens.
