The stealer packed the stand-ins
On October 15, Symantec reported that Aoki, an infostealer first seen this year, now goes after coding-agent credentials: .claude.json, Codex's config.toml and .env files, tokens for GitHub Copilot, Cursor, Gemini, JetBrains AI Assistant and Kiro, and AWS keys. In Bromure Agentic Coding, every one of those files holds a stand-in, the sign-ins and keys stay encrypted on the Mac, and a stand-in sent to a stealer's server pauses the machine.
The stealer's list now starts with your coding agent. It wants .claude.json, the Codex config and the .env files next to it.
An infostealer used to go for browser cookies, saved passwords, crypto wallets and Discord tokens. Aoki still takes all of those. Recent builds also look for the files your coding agent keeps in your home folder.
Symantec's Threat Hunter Team described the change on Wednesday, October 15, in Aoki: Infostealer Targets AI Coding Assistant Credentials. Infosecurity Magazine covered it the same day. Aoki, also called Aokigahara after a string in its decryption routine, first appeared earlier this year. Symantec writes that "earlier versions of the malware did not target AI-related files." The newest sample does.
What Aoki takes
Symantec lists the agent files in the newest sample:
.claude.jsonand Claude desktop cookies.- ChatGPT cookies.
- Codex's
config.tomland.envfiles. - The Cursor local state database, which "can cache chat context and code snippets."
- Tokens for GitHub Copilot, Cursor, Google Gemini, JetBrains AI Assistant and Kiro.
- AWS credentials.
The rest of the list is the usual infostealer haul: more than forty
browsers, about ninety wallet extensions, desktop wallets, password managers,
Telegram, Discord, FTP and VPN clients. Aoki also searches for any file whose
name contains secret, privatekey, keystore, mnemonic, passphrase
or backup. Symantec notes that "the malware has no backdoor command list."
It collects what it finds and posts it to a /gate endpoint on its
command-and-control server.
Symantec explains why the agent files are worth the trouble: "Like card data, a stolen AI key can be cashed in directly." The buyer runs up usage on your account, which is the practice known as LLMjacking. The same tokens "can allow attackers to carry out activity under a legitimate user's identity" and can reach the repositories, cloud accounts and CI/CD pipelines the account is connected to.
Symantec does not say how Aoki gets onto a machine. On a developer laptop
with a coding agent, the obvious way in is a package. The agent installs
dozens of them on its own each day, and a malicious dependency with a postinstall script runs with the agent's
permissions the moment npm install finishes.
The same list in a Bromure machine
In Bromure Agentic Coding the agent runs in a Linux VM on your Mac. Real credentials never enter that VM. The Mac keeps them in an encrypted vault and writes stand-ins into the VM, shaped like the real thing so every tool accepts them. A proxy on the Mac swaps each stand-in for the real value on the wire, and only on requests to the host the credential belongs to.
Put a stealer with Aoki's list inside that VM and walk it through its checklist.
.claude.json and the Claude key
Claude Code in the VM runs on sk-ant-api03-brm-…, a stand-in key. If you
signed in with a Claude subscription, the OAuth tokens were captured on the
Mac during sign-in and stored in claude-subscription.enc, encrypted. The
host refreshes the access token about five minutes before it expires and
injects it into requests bound for Anthropic. The VM never holds a refresh
token, so neither .claude.json nor anything else in the home folder has a
live Claude credential for the stealer to take.
Codex's config.toml, auth.json and .env
Codex gets a seeded ~/.codex/auth.json holding a bogus JWT with a
far-future expiry, so the client doesn't try to refresh it. The real
ChatGPT sign-in sits on the Mac in codex-subscription.enc. An OpenAI API
key appears in the VM as sk-brm-….
A project .env imported with Import env file… in the machine's
Credentials pane comes back under the same variable names, each value a
brm_… stand-in scoped to the hosts you choose. Your code reads
STRIPE_KEY the same way it always did, and the stealer reads brm_….
GitHub, AWS and SSH
~/.git-credentials and GH_TOKEN hold a ghp_ stand-in, 40 characters
like the real thing. There is no ~/.aws/credentials. ~/.aws/config
points at a credential_process helper that hands the AWS SDK the real
access key ID with a 40-character fake secret key, and the Mac re-signs
every request on its way to AWS. A stealer that copies the helper's output
gets a secret key that produces only InvalidSignatureException.
The keyword sweep for privatekey or id_ed25519 turns up nothing.
SSH_AUTH_SOCK in the VM is a bridge to a signing agent on the Mac, and the
private key bytes never cross it.
Cookies
Aoki wants Claude desktop and ChatGPT cookies. The machine's VM has no desktop app and no browser profile to read. When you sign in to Claude or ChatGPT for Bromure, the sign-in page opens in your Mac's browser and the tokens land in the vault. The agent browses with a Chromium that runs in its own disposable sidecar VM, separate from the machine's VM, so a stealer in the agent's VM can't reach the browser's profile.
The upload to /gate
Aoki finishes by posting its haul to /gate. Symantec names
dobeqnesmot[.]cc, hjazfioe[.]surf and neihite[.]cc. In a Bromure
machine, that request has to leave through the proxy on the Mac, because the
proxy is the VM's only route to the network.
The proxy scans every outbound request, headers and body, for stand-ins
headed anywhere other than the host they were minted for. A
sk-ant-api03-brm-… value has one legitimate destination family, Anthropic.
A ghp_ stand-in belongs to GitHub. Inside a POST to a .cc domain, they
can only mean exfiltration. The proxy answers HTTP 451 and forwards nothing.
The VM pauses on the spot, and the Mac shows This environment may have
been compromised, with one line per leaked stand-in: a token preview, the
credential's name, the host it belongs to and the host the stealer tried.
You choose what happens next. Save for Investigation exports the VM's disk, its home folder and the shared folders to a folder you pick, then shuts the machine down. Shut down stops it and marks it compromised. A compromised machine boots again only after Wipe and Launch, which replaces the disk and the home folder and keeps your tokens, SSH keys and settings. Your Claude sign-in, your GitHub token and your AWS keys were never in the VM, so the stealer copied nothing that needs rotating.
You can also stop the upload before the scan. In the machine's Guardrails
pane, set Unmatched traffic to Deny under Outbound connections
and list the hosts the machine needs. A connection to an unknown .cc
domain is then refused, and the Security Timeline shows a red Firewall
row for it.
If the stealer packs its haul so the scan can't read the stand-ins, the server at the other end still receives values that authenticate nowhere. A stand-in works only when it passes through your Mac's proxy on its way to the host it was minted for.
Before the stealer runs
The likeliest way into an agent's VM is a package the agent installed. The machine's Supply Chain pane checks every fetch on the Mac before the VM sees it:
- The age gate, on by default with a two-day minimum, hides package
versions younger than the cutoff. A hijacked release that is yanked within
hours never reaches
npm install. - Install-script stripping, when you turn it on, removes the
preinstall,install,postinstallandpreparehooks from every npm tarball in flight, the usual way npm malware runs on install. - OSV, socket.dev or Depi block versions with known advisories and packages flagged as malware or typosquats, with a 451 whose reason the package manager prints verbatim.
Every fetch shows up in the Security Timeline, so after an incident you can find the package that brought the stealer in.
If the stealer runs on the Mac
Aoki's file list also names what a stealer finds on the Mac itself, and a
Bromure install adds nothing to it. Bromure doesn't import your Mac's own
Claude or Codex CLI logins and doesn't need them: the agents run in the VM,
and their sign-ins live in the vault. Everything under
~/Library/Application Support/BromureAC/ that holds a secret is AES-GCM
ciphertext. The master key sits in the Data Protection Keychain, scoped to
Bromure's signing identity, and never syncs. A stealer that copies the
folder takes encrypted blobs.
Symantec singles out Cursor's local database because it caches chat context and code. Bromure's record of what the agent did, the session trace, is encrypted at rest with the same vault key, and it stores token swaps as first-and-last-character previews only. No real secret appears in a trace, encrypted or not.
Every file on the list holds a stand-in
.claude.json, Codex's auth.json and config.toml, imported .env values, git credentials and AWS config all carry stand-ins. Refresh tokens and SSH private keys never enter the VM.
The upload stops the machine
The proxy finds stand-ins headed for a host they weren't minted for, answers 451, pauses the VM and names each leaked credential.
Nothing to rotate
Wipe and Launch replaces the disk and home and keeps your keys. The stealer took values that only work through your Mac's proxy.
The door is watched
The age gate, install-script stripping and reputation checks run on the Mac before a package reaches the VM, and every fetch is logged.
The list will grow
Symantec says Aoki's capabilities "still appear to be in active development," and other stealers will copy its list. Aoki added the agent files because stolen agent keys and sign-ins sell. Run your agents in a Bromure machine and the buyer gets a bundle of stand-ins that no server outside your Mac's proxy will accept.
For the everyday version of the same problem, where the agent itself copies a secret into its transcript, read The transcript kept the token. For a worm that went after the same files from a compromised npm package, read Revoking the token was the trigger.