Web applications sometimes use system commands as part of their features. Imagine a web application that lets you enter an IP address, then pings this address to check if the host is accessible. In order to do this, the app could maybe use the ping command to do the job.
Bottom line: a web app running on a linux server can use linux commands to do some of the things it needs to do. The same way, a web app running on a Windows server can use some command prompt features to do its job.
Now a command injection vulnerability happens when a malicious user can abuse the app by sneaking in an extra system command in a given input field on a web page.
How do you do it?
To do this, the user may add a
& sign at the end of their regular input and include another command behind it. If user input is not sufficiently sanitized, then both commands will be run sequentially.
One interesting bonus to keep in mind is that commands injected in this way will run with the same privileges that the web application has on the system.
In the example above, suppose the user types an IP address in an input field displayed on the web page, then the page displays the result of a ping command sent to that address. A payload to insert could be something like this:
192.168.1.1 & cat /etc/passwd
If the web app is running on a linux server (and without proper input filtering), this payload will print the result of the ping command followed by the content of the
/etc/passwd file, which contains valuable data on the users of the system (remember reading the
/etc/passwd file doesn’t require admin privileges).
Use the same logic to also retrieve the content of the
/etc/shadow file, which contains the corresponding password hashes. With the content of these two files, you then have something fun to play with.
It’s not always that simple
Of course, things don’t always work out this easy. In some cases, the result of system commands included as outlined above will not necessarily be output to the web page. In this case, you will need to use workarounds to first check if the input field is permeable to command injection, then get the leaked data back to where you can read it.
If you want to dig deeper, TryHackMe has a room dedicated to command injections that you may want to check out (and actually the example outlined in the first section of this post is greatly inspired from that room).