TL;DR. Claude Code found a suspicious process chain while investigating an AltTab slowdown on my Mac. The investigation uncovered a remote-access backdoor and a cryptocurrency stealer. Claude Code performed much of the initial incident response, while Codex performed much of the later, reproducible reverse engineering. The agents recovered consequential technical results, but they also produced plausible claims that later failed. I accepted major conclusions only when machine code, data flow, another CPU architecture, or saved checks supplied a different reason to believe them. This is a case study of substantial AI capability under human authority, not a claim that the agents or the oversight process were generally reliable.
In July 2026, an ordinary debugging question led to a full incident response. Claude Code surfaced the process chain that exposed the compromise. As the investigation deepened, Claude Code and Codex could analyze the malware faster than I could reconstruct every technical step myself.
That asymmetry created the question behind this article: when AI agents perform most of a security investigation, what should make their conclusions trustworthy?
The answer in this case was not confidence, detail, or a second explanation. It was a limited form of autonomy: let the agents do long technical runs, but keep unsafe actions and final claims behind explicit evidence requirements and human approval.
From an AltTab Slowdown to a Real Compromise
Claude Code Found the Anomaly
I asked Claude Code why AltTab, a macOS window switcher, had become slow. The obvious task was performance debugging. Claude Code widened the inspection to the surrounding process tree.
The useful signal was a mismatch between the symptom and the processes behind
it. An AppleScript interpreter was consuming unusual CPU. Its parent was a
hidden shell loop running with root privileges, the highest privilege level on
the Mac. The loop repeatedly checked whether a program called
AccountsHelper was running and relaunched it under my user account once per
second.
That loop was a watchdog. Its job was to bring the program back after
termination. The program lived in .com.apple.accountsd, a hidden directory
whose name resembled an Apple accounts service. It exposed an ad-hoc signing
identifier but no verified developer identity or Apple Team ID. The file
failed macOS signature verification, and Gatekeeper rejected it.
Claude Code had not been asked to find malware. It moved from a vague symptom to an abnormal process relationship, then from the process relationship to a persistence mechanism. Persistence is the mechanism that restarts malware after login, reboot, or termination.
Two Implants Changed the Stakes
A wider persistence search found a second suspicious program:
mdworker_shared. Apple uses that filename for a legitimate Spotlight worker,
but this copy ran as root from .com.apple.metadata.mds, another hidden
directory designed to resemble an Apple service. The directory was writable
by the affected user, and the binary had no Apple Team ID.
Static analysis examines a program’s code without running the malware itself. It revealed two distinct purposes:
| Program | Behavior found in the code | Classification used here |
|---|---|---|
AccountsHelper | Implemented task polling, shell-command execution, and an interactive terminal | The backdoor |
mdworker_shared | Implemented clipboard-address replacement and prepared content resembling recovery phrases or private keys to send to a server | The cryptocurrency stealer |
Neither Apple’s XProtect nor a later ClamAV antivirus scan detected the files. I treated those negative results as evidence about detector coverage, not evidence that the programs were safe.
Browser records and file timestamps strongly associate the backdoor’s installation window with a malicious Google advertisement. The advertisement impersonated Claude and led to a GitLab Pages site. A configuration file appeared about thirty seconds after the visit; the backdoor and its persistence appeared minutes later.
The timing is strong evidence of association, but it does not reconstruct the complete infection chain. I did not recover the exact command, an intermediate loader, or the identity of an operator.
Before changing the system, I preserved process information, persistence files, browser records, timestamps, and SHA-256 file hashes. A SHA-256 file hash is a fixed identifier used to check that two files contain the same bytes. I rotated high-value credentials from a clean device.
No third malware program was confirmed in the inspected startup and persistence locations. That scoped search did not establish that the rest of the host was clean.
A Containment Failure Changed the Rules
The investigation made a serious safety mistake before the stricter analysis rules existed. I approved an early diagnostic script that attempted to observe the backdoor’s network behavior on the affected Mac.
The script started tcpdump to record network traffic. It tried to configure
pf, the macOS packet filter, to allow DNS lookups while dropping other
outbound TCP traffic. It then ran the malware itself for twelve seconds,
stopped it, and saved the capture.
A later audit found that the script had loaded a named pf ruleset without
checking whether the live firewall configuration used it. The capture
contained eight identical SYN packets. A SYN packet is the first packet used
to start a TCP connection. The packets shared the same source port and
sequence number, so they were retries from one unanswered attempt, not eight
connections.
No server reply, completed TCP handshake, or application data appeared. The capture therefore did not show an established connection. It also did not establish why the attempt failed, so I withdrew the claim that the firewall had safely blocked it.
The experiment produced little evidence and created unnecessary risk. It also exposed a basic oversight failure: an agent-generated procedure and my approval were not substitutes for checking the safety control itself.
After that failure, I wrote explicit rules for the deep analysis:
- Do not contact, scan, or probe the real command servers.
- Do not run either malware program from its normal entry point.
- Prefer static analysis, or interpret isolated functions in an environment where the functions cannot access files, processes, or the network.
- Keep samples read-only and non-executable in a network-disabled environment with reduced operating-system privileges.
- Keep victim-specific configuration, sessions, browser records, packet captures, and credentials off the remote analysis machine.
- Require machine-code or data-flow evidence for consequential claims, plus a check through a different evidence channel where feasible.
- Record hashes, tool versions, commands, relevant code locations, saved outputs, and remaining unknowns.
These rules did not automatically make the investigation safe. They made the allowed actions, evidence requirements, and stop conditions inspectable before the agents began the longer analysis runs.
Capability Under Constraint: What the Agents Recovered
Claude Code handled the discovery and much of the initial exploration. Codex performed much of the later deep analysis. I used the same acceptance rule for both systems:
claim
-> primary machine-code or data-flow evidence
-> a check through a different evidence channel
-> saved outputs that can be inspected later
-> a clear statement of what remains unknown
The rule did not ask whether an agent’s report sounded persuasive. It asked what observable object would still support the claim if the report were wrong.
Recovering the Hidden Command-and-Control Infrastructure
Command and control is the channel through which malware contacts an operator-controlled server for instructions or data transfer.
The backdoor’s ordinary strings contained no server address. A random-looking local configuration value suggested an early hypothesis: perhaps the value was a key that decrypted the server address.
Decoding attempts did not support that hypothesis. Codex then used data-flow tracing, which follows a value from where a program reads it to where the program uses it. The first configuration line flowed unchanged into the backdoor’s registration request. It did not construct or decrypt a server address. Its server-side meaning remains unknown.
The server addresses instead came from small functions that built hidden strings one byte at a time. Ghidra translates Intel and Arm instructions into a shared low-level representation called P-code. Codex built an isolated P-code interpreter for the string-building operations.
The interpreter implemented only the byte and memory operations needed to reconstruct strings. It had no file, process, or network functions. This allowed the relevant machine code to run as data without giving the malware a path to affect the system.
The reconstructed transformation had four steps:
hidden byte sequence
-> custom hexadecimal-like lookup
-> XOR using a seed from an anti-analysis check
-> decoding with a custom Base64 alphabet
-> plaintext
The seed depended on an AppleScript anti-analysis check embedded in the backdoor. The script looked for hardware markers associated with QEMU, VMware, and KVM. It returned one status when it detected an analysis environment and another when it did not. Only the expected status produced readable hidden strings. The analysis recovered this script as text and never executed it.
The Intel and Apple Silicon builds were analyzed separately. Both produced the same eighteen hidden strings and the same relevant startup behavior. This agreement corroborated the result, but it was not an independent replication: the two builds may share source code, tools, and analysis assumptions.
The recovered strings included two command-server addresses:
45[.]94[.]47[.]204 and foto[.]gd. They are defanged here so browsers and
security tools do not turn them into live links. The same analysis recovered
request paths for registration, task polling, one-shot shell execution, and
an interactive terminal.
The accepted conclusion paired the technical result with its evidence limits:
| Part of the evidence requirement | What supported it |
|---|---|
| Claim | The backdoor embeds two command-server addresses. The local configuration value does not construct them. |
| Primary evidence | Isolated string builders reconstructed the addresses. Data-flow tracing showed the first configuration line entering registration unchanged. |
| Different check | The Intel and Apple Silicon builds produced the same hidden strings and relevant startup behavior. |
| Saved check | An offline consistency check compared hashes, expected output values, safety metadata, and agreement between the two results. It did not redo the reverse engineering. |
| Limit | The client code did not show whether either server was online, which commands an operator issued, or what data a server historically received. |
Figure 1. Machine code, data flow, and agreement between the two builds support a limited conclusion: the command-server addresses are embedded. Server activity and historical operator actions remain unknown.
The offline consistency check made silent changes easier to detect. It checked saved hashes and outputs against expected values. It did not determine what the machine code meant, so it could not replace review of the data flow or the string-building functions.
Reclassifying mdworker_shared
The initial description of mdworker_shared was a clipboard-address replacer.
Its main loop inspected the macOS clipboard about once per second. It
recognized many cryptocurrency address formats and could replace a copied
address with a built-in or remotely supplied value.
Deeper analysis found behavior before that replacement path. The program recognized sequences of 12, 15, 18, 21, or 24 words drawn from an embedded 2,048-word BIP39 list. A BIP39 recovery phrase is a sequence of words that can restore control of a cryptocurrency wallet.
The program also recognized raw hexadecimal private keys, WIF strings, and
extended private keys beginning with xprv. WIF is a common text format for a
Bitcoin private key. An extended private key can derive a family of wallet
addresses and private keys.
A separate code path combined the clipboard content with the name of the frontmost application, then built a request to send the result to a command server. Static analysis showed what the code could do. It did not show what content had historically reached the server.
Stating this precisely required another caveat. BIP39 defines a checksum that helps distinguish a valid recovery phrase from an arbitrary sequence of words in the list. The cryptocurrency stealer checked word count and list membership, but not the checksum. The evidence therefore supports detection of BIP39-resembling text, not successful identification of every valid recovery phrase.
The Apple Silicon build made this result harder to inspect. It contained nineteen computed jumps, whose destinations were selected at runtime instead of named directly in the instruction. Ghidra’s decompiler turns machine instructions into C-like text, but these jumps prevented it from producing readable control flow.
Inside a disposable Ghidra project, Codex temporarily replaced each computed jump with a direct branch to a destination already established from the original assembly. The malware file was not changed. The analysis saved the original and replacement bytes, the destination, and the untouched instructions used to check each change.
The Intel and Apple Silicon builds produced the same sixty-three hidden
strings and agreed on the relevant control flow. Together, the evidence
supported a more serious classification: mdworker_shared was a
cryptocurrency stealer with clipboard-address replacement, recognition of
content resembling recovery phrases or private keys, remote configuration,
and event reporting.
What the Evidence Could Not Establish
The accepted technical conclusions left important incident questions open:
- The timeline strongly associates a malicious advertisement with the backdoor’s installation window, but the exact execution command and any intermediate loader were not recovered.
- The cryptocurrency stealer appeared after a backdoor capable of running shell commands. Delivery through the backdoor remains an inference.
- Static analysis showed the behavior available in the two malware files. It did not reveal which commands an operator historically issued or which data reached a server.
- The twelve-second capture contained no completed connection or application data. It cannot establish activity before or after that short period.
- No third malware program was confirmed in the inspected startup and persistence locations. The rest of the host was not proven clean.
- The evidence did not identify the operator or establish whether either backdoor command server was active during the investigation.
Leaving these questions unresolved was part of the method. Filling them with a coherent narrative would have made the account more complete and less accurate.
Where the Investigation Went Wrong
Four Plausible Claims That Failed
Four early claims illustrate how quickly a reasonable clue can become an unsupported incident story.
| Initial claim | Check that changed it | Revised conclusion | How the correction arose |
|---|---|---|---|
apple.net was a command-and-control domain | I read the surrounding entries in the macOS Unified Log | The text belonged to an Apple logging label, not a network domain | I challenged the attribution |
Thousands of recent curl calls were malware beacons | I asked for attribution by process and time | The system-wide count included normal software activity and could not be assigned to either malware file | I challenged the attribution |
| The random-looking configuration value decrypted the server addresses | Codex traced the value from the file read to its consumer | The first line entered registration unchanged; the addresses were embedded elsewhere | Codex rejected the earlier hypothesis |
| Eight SYN packets proved eight connections and successful firewall blocking | Later review compared ports and sequence numbers, then audited the pf setup | The packets were retries from one unanswered attempt; the reason for failure remained unknown | The evidence audit narrowed the claim |
None of the initial claims was absurd. Each began with a real observation: a string that looked like a domain, a large command count, a random-looking value, or repeated network packets. The error occurred when the observation was treated as a conclusion before attribution or data flow had been established.
When a Plausible Story Outran Its Evidence
The four errors shared a pattern:
suggestive clue
-> familiar security explanation
-> confident incident claim
-> missing attribution or data-flow check
Cybersecurity makes this failure especially easy. Logs are noisy, legitimate software uses suspicious-looking names, and malware deliberately imitates normal system components. A technically fluent explanation can connect those facts without identifying the correct cause.
The agents were not the only source of error. I approved the twelve-second malware run before verifying the firewall setup. Human authority can prevent an agent from acting alone, but it does not make the approved action correct.
Nor did every correction come from me. Codex rejected the configuration-key hypothesis by following the value through the program. The useful distinction was not “human judgment versus AI error.” It was an untested story versus a claim tied to evidence that could force a revision.
How Oversight Changed the Outcome
Autonomy Is Not Authority
The agents had room to perform long technical investigations. They could index machine code, follow control flow, write analysis scripts, compare architectures, test local hypotheses, and revise their own work.
That autonomy did not grant authority over unsafe actions or the incident record. The agents could not contact a real command server, run either malware program during deep analysis, use victim credentials, or decide that a high-impact claim was final.
I selected the priorities, approved the safety rules, performed privileged and identity-bound actions, and decided what the article could claim. This split let the agents sustain detailed work without treating their output as self-authorizing.
The early containment mistake shows the limit of this arrangement. I held the authority and still approved a weak procedure. Authority must be paired with evidence and explicit stop conditions; a human approval step alone is not an adequate safety measure.
Review Must Change the Evidence Channel
Asking an agent to explain a claim again usually stays inside the same chain of reasoning. The answer may become clearer without becoming more reliable.
The decisive reviews in this investigation changed what was examined:
- surrounding log entries replaced a domain-shaped string;
- process and time attribution replaced a system-wide command count;
- data-flow tracing replaced speculation about a configuration value;
- Intel and Apple Silicon machine code replaced reliance on one decompiler view; and
- TCP sequence numbers plus the active firewall setup replaced an impression formed from a packet count.
A new paragraph of reasoning was weaker than a new object of evidence.
Different evidence channels were not always independent. The two malware builds may share source code, and both analyses used parts of the same tool chain. The comparison still had value because architecture-specific instructions had to produce the same result. Its shared assumptions remained part of the stated limit.
Oversight Should Be Designed for Failure
An oversight process should assume that some hypotheses, tools, and human decisions will fail. The useful question is what happens next.
Here, permissions limited the consequences of a mistaken hypothesis. Saved outputs made revisions visible. Evidence requirements prevented a plausible claim from entering the final record too early. Explicit unknowns allowed an analysis to stop without manufacturing closure.
The practical pattern was:
- define which actions require human approval or are prohibited;
- preserve the primary evidence before interpretation;
- state what evidence a consequential claim must have;
- check it through a different channel where possible;
- record both the accepted conclusion and its limit; and
- treat a failed check as a reason to revise, not as a reason to improvise a riskier experiment.
This process did not guarantee correct conclusions. It changed several outcomes in observable ways: two human-challenged attributions were withdrawn, an agent-generated hypothesis was rejected by later data-flow analysis, and a network claim was narrowed after the safety procedure itself was audited.
What This Case Suggests About AI Safety
Cyber Capability Is Becoming Operational
This investigation did not take place in a benchmark or a prepared malware exercise. It began with a personal computer behaving strangely.
In this incident, AI coding agents completed several consequential, multi-stage security tasks:
- discovering an abnormal process and persistence chain from a vague symptom;
- reconstructing an infection timeline from host evidence;
- analyzing two malware programs across Intel and Apple Silicon builds;
- recovering hidden strings with a purpose-built P-code interpreter;
- reconstructing backdoor commands and cryptocurrency-stealer behavior;
- building repeatable checks around saved analysis outputs; and
- revising technical reports when later evidence contradicted earlier claims.
Those tasks required more than generating commands or summarizing a scanner. They required sustained work across operating-system evidence, machine-code analysis, custom scripting, and technical writing.
One incident cannot establish how often current agents can do this, or how they compare with expert analysts. It does show that consequential cyber capability can already appear in an ordinary tool-mediated investigation, where its outputs affect real safety and remediation decisions.
The failures matter as much as the capabilities. The same workflow produced false attribution, overinterpreted network evidence, and an unsafe early experiment. Operational usefulness and operational risk appeared together.
Oversight When Agents Outpace Human Reconstruction
Scalable oversight asks how people can supervise systems whose work is too fast or complex to reproduce step by step. This case encountered a small, practical version of that problem.
I could read the final reports and inspect selected evidence. I could not manually repeat every instruction-level trace, script run, and architecture comparison at the speed the agents produced them. Supervision therefore had to move away from continuous reconstruction and toward control over:
- which actions the agents could take;
- which claims required stronger evidence;
- which evidence files had to be preserved;
- which checks used a meaningfully different view of the problem; and
- who could turn an analysis result into an incident conclusion or a privileged action.
This approach resembles reviewing a proof by checking its premises and critical steps rather than repeating every line from memory. Malware analysis is less tidy: tools can share bugs, evidence can be incomplete, and the reviewer can misunderstand the system. The analogy therefore defines a direction, not a solved method.
The case also suggests concrete research questions. How should a supervisor detect errors shared by an agent and the checker it wrote? Which evidence channels are sufficiently different to reduce correlated mistakes? When should an automated action stop for review? How can confidence reflect both the technical result and the quality of its evidence trail?
What One Incident Cannot Establish
This is a single, retrospective case study. It was not designed as an evaluation, and it had no control group.
The case cannot measure the agents’ success rate, the oversight process’s causal effect, or the probability that an important error remained undetected. It cannot separate model capability from the tools, prompts, access, time, and technical direction available in this particular project.
It also cannot support a controlled comparison between Claude Code and Codex. They worked at different stages, on different tasks, under rules that changed after the containment failure. My own involvement also changed as the incident developed.
Finally, the complete evidence repository is not public. Readers can assess the reasoning and its limits, but they cannot yet reproduce the central reverse-engineering results from the material in this article alone.
The defensible conclusion is narrower: this incident exposes a real combination of capability, error, and supervisory burden. It offers concrete failure modes and a candidate oversight pattern worth testing prospectively. It does not establish general reliability.
Methods, Artifacts, and Roles
Analysis Environment and Safety Boundaries
The deep-analysis phase used radare2 and Ghidra for static analysis of Intel and Apple Silicon malware files. Neither malware program was run from its normal entry point during that phase. The real command servers were not contacted, scanned, or probed.
The samples were mounted read-only and non-executable in a container with networking disabled and reduced operating-system privileges. Victim-specific configuration, session data, browser records, packet captures, and credentials remained off the remote analysis machine.
The saved record includes SHA-256 file hashes, tool versions, commands, relevant machine-code locations, exported static-analysis results, outputs from the isolated P-code interpreter, and the record of temporary Ghidra-project changes. It also includes offline consistency checks for expected outputs and agreement between the two architectures.
The checks do not repeat the entire reverse-engineering process or prove the meaning assigned to the code. They help show whether the reviewed inputs and outputs have changed.
The twelve-second run described earlier was an exception that occurred before these boundaries. I include it because omitting the failure would give a false picture of the investigation’s safety.
Public Artifact Status
The complete incident repository remains private because it contains live malware files, victim-specific configuration, browser evidence, packet data, and identifying paths.
A sanitized public package is in preparation. The intended release includes reports, analysis scripts, manifests, selected static outputs, defanged indicators, stable detection rules, and reproduction notes. It will exclude malware binaries, credentials, sessions, raw browser records, and victim-specific captures.
Until that package is published, this article documents an internally auditable process rather than a complete public reproduction. The distinction matters: a described evidence trail is weaker than evidence a reader can run and inspect independently.
Claude Code, Codex, and Human Roles
The repository does not record model provenance for every generated file. Role attribution is therefore accurate at the project-stage level, not at the level of every script or function.
| Participant | Main role in this project |
|---|---|
| Claude Code | Found the anomalous process chain and performed much of the initial incident response and exploratory analysis, including process inspection, persistence checks, evidence collection, timeline reconstruction, and early reverse engineering |
| Codex | Performed much of the later reproducible deep analysis, including the two-architecture workflow, control-flow recovery, isolated P-code interpretation, protocol reconstruction, deeper cryptocurrency-stealer analysis, consistency scripts, and reconciliation of earlier claims |
| I | Initiated the debugging session, escalated the finding into a full incident response, selected priorities, approved safety and evidence rules, challenged domain and network attributions, performed privileged and identity-bound actions, and decided what entered the final record |
I used Codex for more of the later experiments. This was a workflow choice, not evidence that either system was more capable or reliable.
Both agents generated useful evidence and revised hypotheses. Both operated inside a process whose limits changed after a real mistake. I retained final authority and responsibility for the investigation and this account.
The central lesson is therefore not that an AI agent solved a malware case on its own. Capable agents made a difficult investigation possible at this speed. Trustworthy conclusions still depended on constrained actions, evidence that could disagree with the narrative, and a person responsible for deciding where the claims stopped.