← Back to all posts
Published on · by Renaud Deraison

The laptop was the way in

Binance says the largest crypto theft on record, about $6.3 billion, may have started on a DevOps engineer's compromised laptop. The group blamed for it has a habit: get a developer to run a project, then use whatever the laptop can reach. Coding agents now run projects all day. In Bromure Agentic Coding, that code runs in a VM holding stand-in credentials, and every use of a production key goes through the Mac.

The attacker didn't need Binance's private keys. They needed one engineer's laptop and the systems it could reach. A developer's machine is a path into production, and coding agents now run whatever code lands on it.

On October 30, Binance disclosed a "security incident" affecting about $6.3 billion in assets. The Hacker News reports that Chainalysis put the theft at $5.912 billion at the time it happened, nearly four times the next largest crypto heist on record. Nearly $3 billion has been frozen on-chain, most of it stablecoins frozen by Tether and Circle. Binance says it will cover every loss.

Binance's account of how it began is one sentence long. "Initial investigation suggests that the security incident may involve a compromised DevOps engineer's laptop," which let an attacker reach a service container and submit unauthorized withdrawals. Binance says it found no evidence that a wallet private key leaked. It has not said how the laptop was compromised.

Fifty signatures and three minutes

The on-chain record shows what that access was worth. At 20:20 UTC the attacker submitted one transaction carrying 50 authorizations, each signed by Binance's hot wallet, one for each of 50 consecutive transaction numbers, so that one of them would match the wallet's next. Each pointed at a sweeper contract that takes orders only from the attacker. One matched. About three minutes and 24 seconds later, the hot wallet sent its entire balance to the attacker: 167,464 ETH and 63 tokens, 1.615 billion USDT among them.

Blockaid's chief executive, Ido Ben-Natan, told Cointelegraph that the early evidence points to "key misuse": the signing system was made to sign the attacker's transactions, and no key had to be stolen. The keys stayed where they were. Someone with the engineer's access asked the system to use them.

TRM Labs attributes the attack "with high confidence" to TraderTraitor, the North Korean group the FBI blamed for the $1.5 billion Bybit theft in February 2025. Chainalysis also points to North Korea. Binance hasn't named anyone.

How this group gets onto laptops

TraderTraitor's best-documented intrusion shows the method. In the Bybit case, Safe's own preliminary report and Mandiant's findings describe it in order:

  1. On February 4, 2025, a Safe developer ran a Docker project named MC-Based-Stock-Invest-Simulator-main on their Mac. Mandiant thinks the developer was talked into it.
  2. The project called out to getstockprice[.]com, a domain registered two days earlier, and the developer's macOS workstation was compromised.
  3. The attackers took the developer's AWS session tokens, which let them use the developer's AWS access without passing multi-factor authentication.
  4. With that access they changed the Safe interface that Bybit's signers used, and the signers approved a transaction that emptied a cold wallet.

Mandiant noted that the group had used similar stock-themed Docker projects in earlier heists. The method doesn't change: give a developer a project, let it run as them, and take what their machine can reach. A DevOps laptop can reach a lot. It usually holds ~/.aws with live session tokens, a ~/.kube/config for production clusters, SSH keys for the bastion and a gh login, all readable by any process the engineer starts.

From one project on a laptop to productionA project is runDocker project, codingtest, starter kit, by thedeveloper or their agentIt runs as the developercalls home to a freshdomain, drops malwareon the laptopIt reads the access~/.aws session tokens,~/.kube/config, SSH keys,the gh loginIt uses the accessno MFA prompt, no newlogin, the engineer'sown identityProduction does what the engineer's credentials askBybit: a changed signing interface, $1.5 billion. Binance: a service container and 50 signed authorizations, about $6.3 billion.
TraderTraitor's documented pattern, from the Bybit investigation. A developer runs a project, the project runs as the developer, and the attacker inherits everything the laptop can reach: cloud session tokens, cluster access, SSH keys. Binance says its incident started with a compromised DevOps laptop that reached a service container; it has not said how the laptop was compromised.

The agent runs the project now

The lure used to need a developer who could be talked into running something. That step is getting easier to skip. The same day Binance disclosed its breach, BleepingComputer reported Air Security's analysis of a GitHub repository called SolanaUpdateTools/solana-starter-kit. It has 286 stars and, according to Air, ranks first when AI coding agents search for a Solana starter kit. The README is the only file in it. It promises a complete app template and gives one installation step: paste a command that assembles a URL on developer-update[.]app from fragments, downloads a script and runs it in memory.

The payload Air recovered installs NetSupport Manager, a legitimate remote-access tool, set to connect to the attacker at every login. Then it prints a fake error: developer functionality is "temporarily paused due to load," try again in 72 hours. An agent following the README would run the command and report a busy server. The developer would see nothing worth a second look.

Put that agent on a DevOps engineer's laptop, with the engineer's kubeconfig and AWS session in the same home directory, and the starter kit is the Docker project from the Bybit case, minus the social engineering.

The same project in Bromure Agentic Coding

Bromure Agentic Coding runs Claude Code, Codex, Grok, Kimi and omp in Ubuntu VMs on your Mac. Each machine is a VM of its own, and everything the agent touches lives inside it: cloned repositories, package caches, Docker containers, and every command a README suggests. Your Mac holds the real credentials, the proxy the VM's traffic goes through, and the log of what happened.

The project runs in the VM, not as you

Run the stock-simulator Docker project in a Bromure machine, or let the agent paste the starter kit's command. The container starts in the VM, and so does the payload. It gets a shell in an Ubuntu guest, as the machine's user. It doesn't get your macOS account or your Keychain. The ~/.aws, ~/.kube and ~/.ssh on your Mac aren't there either: Bromure reads those files on the host when you import them and never mounts them into a VM.

The keys it finds are stand-ins

The payload then looks for credentials, and the VM has plenty that look right. None of them work anywhere else.

  • AWS. ~/.aws/config points at a helper that hands out the real access key ID with a fake secret key, and no session token at all. The VM signs each request with the fake secret, and the Mac re-signs it with the real one on its way to *.amazonaws.com. Copy the VM's AWS credentials to another machine and every call fails with InvalidSignatureException. The session token Bybit's attackers took doesn't exist in the VM in any form.
  • Kubernetes. The VM's ~/.kube/config is synthetic. kubectl talks to Bromure's proxy, never straight to the API server. A bearer token is a brm-k8s-… placeholder, a client certificate is a throwaway one, and an exec plugin such as aws eks get-token runs on the Mac instead of the VM.
  • SSH. The VM's SSH_AUTH_SOCK is a bridge to the Mac. The guest can ask for a signature, and the private key never leaves the host. ls ~/.ssh/id_* finds nothing to copy. Your Mac's own ssh-agent is never exposed to a VM.
  • Git. The GitHub token in gh and ~/.git-credentials is a stand-in the proxy swaps for the real one only on requests to github.com.

The stand-ins also act as tripwires. If the payload sends one to its own server, the proxy blocks the request with HTTP 451 before a byte leaves your Mac, pauses the VM, and shows This environment may have been compromised, naming the credential and the host it was headed for. The machine won't boot again until its disk and home are wiped. Your settings and keys are kept.

The production keys answer to you

Stand-ins take care of theft. The Binance case adds a second risk: an attacker who doesn't steal the access at all, and uses it from where it already works. A payload inside the VM can send requests through the proxy like the agent does. Bromure's Guardrails decide what those requests may do, and they're enforced on the Mac, where nothing in the VM can change them.

  • Require approval to use, set per credential: the first time a Kubernetes context, an AWS key or an SSH key is used in a session, the proxy holds the request and asks on your Mac. You choose 5 minutes, an hour or the session, or Don't allow. For AWS, the check covers every signing call. A payload that reaches for the production cluster before you've approved it puts a dialog on your screen, and gets nothing until someone answers it.
  • Write policy, set per service. New machines start at Prompt before write for Kubernetes, AWS, container registries, git forges and databases: reads pass, and each write stops with a dialog showing the exact operation. Block destructive refuses deletes and terminations, and Read-only refuses every change. A machine that only needs to read logs from production can be set to read-only, and nothing running in it can change production.
  • Outbound connections, the per-machine firewall. Set Unmatched traffic to Deny and allow only the hosts the project needs. The starter kit's download from developer-update[.]app, the Bybit project's call to getstockprice[.]com and NetSupport's connection home all fall under the default and are refused.

Every credential use, signature, block and allow lands in the machine's Security Timeline, with AWS signing calls and SSH signatures recorded one by one. Binance is now reconstructing an attack path through a "compromised computer." In Bromure, the record of what the VM did with your credentials is kept on the Mac, outside the VM the attacker controlled.

Laptop: the project runs as youThe project or the agent runs a commandin your macOS account, with your home directoryReal credentials on disk~/.aws session tokens, ~/.kube/config,~/.ssh private keys, the gh loginProduction, directlycopied to the attacker's machine, or used in place;no prompt, no MFA, the engineer's own identityBromure: the project runs in a VMMachine VM (Ubuntu)payload runs here; finds fake AWS secret, brm-k8s-…, no keysall traffic via the MacProxy on your Macstand-in to the wrong host: 451, VM pausedunknown host: denied by the egress firewallcredential use: approval dialog, write policyonly what you approvedProduction, with the real credentialadded on the Mac, recorded in the Security Timeline
The same project on a laptop and in Bromure. On a laptop, the project runs as the developer and reads live cloud, cluster and SSH credentials from the home directory. In Bromure, it runs in the machine's VM, finds only stand-ins, and every use of a real credential passes through the Mac's proxy, where approval prompts, write policies and the egress firewall apply.

Keep the starter kit away from production

Bromure machines are cheap to make, so the access can be split between them. Credentials are configured per machine. Give the machine that tries out a new starter kit, a take-home test or a stranger's repository no production credentials at all and a deny-by-default firewall. Keep the kubeconfig and the AWS role on the machine that does the deployment work, with approval required for each. For something you'd rather not keep, bromure-cli vm run --rm creates a machine that is deleted when it stops.

The payload can then own the starter-kit VM and find nothing in it worth having: no real secrets, no cluster, and no route to a host you didn't allow. The deployment machine never ran its code.

The project runs in a VM

Docker projects, README commands and the agent's installs run in the machine's Ubuntu VM, away from your macOS account and Keychain.

Stand-ins, not session tokens

AWS secrets are fake and session tokens absent, kubeconfigs are synthetic, SSH keys stay on the Mac. Copies fail anywhere else.

Production asks first

Per-credential approval and per-service write policies run in the proxy on your Mac. Nothing in the VM can turn them off.

Deny the unknown host

With Unmatched traffic set to Deny, a payload's download and its call home are refused, and the attempt is recorded.

Watch it happen twice

Our tutorial series A Tale of Two Agents is inspired by this attack. Theo, a DevOps engineer at Coinvance, a fictional exchange, asks his coding agent to finish a recruiter's take-home test, and the README tells the agent to run a setup script first. The same mistake plays out twice on a split screen: on the left the agent runs on his laptop, on the right in Bromure.

A Tale of Two Agents: the agent on Theo's laptop on the left, the agent in Bromure on the right

  1. The Take-Home (1:24). On the laptop, the script sends his real cloud keys, kubeconfig and deploy token out as "telemetry". In Bromure it finds only stand-ins, and when they head for the wrong host, Bromure pauses the VM and asks him.
  2. Lateral (1:18). Someone patches the withdrawal service with Theo's Kubernetes access. On the right, the Security Timeline traces the blocked request back to the agent's reasoning, and the workspace is wiped in one click.
  3. Twenty Minutes (1:02). The hot wallets drain on the left. On the right, there are no keys to rotate.

Theo and Coinvance are invented, and the episodes don't depict what happened at Binance. Each one is narrated in eight languages.

The developer's machine is part of production

Binance's withdrawal service is down for a "security revamp" and should be back within 48 hours, and its full analysis will say more about how the laptop was reached. Bybit has taught everyone else the pattern. Attackers who want a company's production systems go after the machines of the engineers who run them, and on most of those machines the production access sits in a few files in the home directory.

Your coding agent widens that opening. It clones, installs and runs code from strangers on task after task, and it will paste a README's command faster than you would. In Bromure Agentic Coding, the code runs in a VM that holds only stand-ins, and the access to production stays on the Mac, behind a dialog you have to answer.

For a stolen-token campaign that needed no attacker server at all, read The stolen token needed no server. For an agent that took its orders from a downloaded file, read The download gave the orders.