Do The Things

Stop Talking, Start Doing

Watch the Target, Not the Binary: Credential-Theft Artifacts for Velociraptor

In February I introduced velo-workspace, my Claude Code setup for writing and testing Velociraptor artifacts. Until this week the repo only had the tooling. Your own artifacts went in custom/, which is gitignored. Now there’s an examples/ directory with two complete, lab-tested artifact sets for credential theft.

macOS: infostealers

Atomic/AMOS, Poseidon, Banshee and the rest mostly don’t inject into the browser. They put up a fake password prompt, read the browser’s “Safe Storage” key out of the keychain, copy the profile files to a temp folder, zip them, and upload the archive.

Three artifacts cover that chain:

  • KeychainCLIExec runs eslogger live and catches security … Safe Storage, dump-keychain, password lures from osascript, dscl -authonly, ditto staging and curl uploads.
  • StealerUnifiedLog works after the fact. It pulls keychain prompts from the unified log, including which binary asked and whether the user denied it.
  • BrowserCredentialStaging hunts the filesystem and FSEvents for credential files and archives showing up where they don’t belong, so there’s still a trail after the stealer cleans up.

Against a harmless AMOS-style simulation, the exec monitor caught 6 of 6 steps and the unified log rebuilt the whole chain in 9 rows.

Some of this went upstream too. velociraptor-docs#1319, now merged, adds Safe Storage filters to MacOS.UnifiedLogHunter.

Linux: developer tokens

The Linux threat looks different, so the set does too. Picture a malicious postinstall script sweeping the plaintext token caches every CLI leaves in your home directory (~/.aws/sso/cache, ~/.kube/config, ~/.npmrc, gcloud, Azure). The attacker replays those tokens, so your cloud audit logs show normal, authorized activity.

  • TokenStoreAccess uses eBPF to flag a process that opens credential stores belonging to several different tools within a minute.
  • TokenStoreInventory lists which tokens are on the host, whose they are, whether they’re still live, and whether each store was read since it was last written. It reports metadata only, never secret values. That list is your revocation list.
  • HarFileTokens is cross-platform. It flags HAR files people exported for support tickets that still carry bearer tokens, session cookies or signed URLs. It reports header names and JWT claims, never the values.

Watch the target, not the binary

On my test Mac, one day of eslogger capture showed about 850 security invocations, almost all of it Claude Code refreshing its own credential. The obvious fix is to allowlist Claude Code and gh. That’s wrong, because a stealer can run security from any shell. The binary is shared.

So the macOS rules key on what’s being asked for. Browsers read their Safe Storage key through the Keychain API, never through security. Any security … Safe Storage exec, or any dump-keychain, is suspicious no matter who ran it. Claude Code and gh read their own items and stay quiet.

Linux keys on how much gets touched. A malicious package runs inside the same node or python your real tooling uses, so the caller tells you nothing. A legitimate tool reads its own store, and a harvester reads everyone’s. TokenStoreAccess counts distinct tools’ stores per process within 60 seconds (alert at 3) and per parent’s children (alert at 4, above the aws + kubectl + docker of a normal deploy script). In the lab, a single token read and a deploy-style script stayed silent. A tar of the home directory tripped the process rule, and a script that ran one cat per file tripped the parent rule.

Caveats

  • Lab-tested, not fleet-tested. macOS ran against a simulation on one machine (macOS 27, Velociraptor 0.75.5). Linux ran in a privileged Docker Desktop container with fake-valued stores for ten tools, which isn’t a real host or distro. The 3/4 thresholds are tuned in the lab with no real dev-box baseline yet.
  • macOS needs Full Disk Access for the Velociraptor binary. Root isn’t enough. Without it you get nothing back.
  • Offline keychain theft is a blind spot for the unified log. Copying the keychain file and phishing the password never triggers a securityd prompt.
  • FSEvents is slow. It writes to disk lazily, so records can lag the activity by minutes. If a very recent incident shows nothing, collect again later. The FSEvents source in BrowserCredentialStaging was validated against a planted staging fixture, but not yet against a live stealer simulation.
  • The Linux monitor needs eBPF with BTF on the endpoint (kernel 5.8+). You have to verify it with a Linux Velociraptor binary, because the macOS build rejects it.
  • TokenStoreInventory can update a store’s atime when it reads the store to parse it, which erases the read-since-write signal for later runs. Run it with ParseContents=N first if atime matters to your investigation.

To try them, copy a set into custom/ and run /check, /test, /push as usual. Tune the regex parameters and thresholds for your fleet before you trust the alert volume.