Published on
Command injection is similar to SQL injection, but instead of injecting into a SQL query, you are injecting a command into the Operating System. User data can be input to alter the intent of the command that is being executed.
This is a dangerous vulnerability because the attacker can do anything at the privilege level of the process. This could include things like downloading tools, stealing or changing credentials, stealing data, or deleting files.
Finding Command Injection
Let's look at command injection with a real application.
This cloud storage site (see the video) shows you a list of files in your account, and allows you to create new files. Lets add a new file.
How might the application be adding this new file? It is possible that it is done via an operating system command. We can test to see if this is the case.
In Linux, you can add additional commands to a single line by adding a semicolon. So we can try typing This to look for anything suspicious.
x; ls;
As you can see, there is no error message, but everything after the semicolon was ignored. That is odd behavior and means there could be a command injection vulnerability, but we are not getting back any feedback.
A blind command injection is a command injection vulnerability where you do not receive visual clues about the vulnerability. To test for a blind command injection you need to use time based feedback. So we submit a command that takes varying amounts of time to see if something is being executed.
Depending on the operating system you may want to try the following payloads to test the timing:
| ping -i 30 127.0.0.1 |
| ping -n 30 127.0.0.1 |
& ping -i 30 127.0.0.1&
& ping -n 30 127.0.0.1&
; ping -i 30 127.0.0.1;
%0a ping -i 30 127.0.0.1 %0a
ping 127.0.0.1
In this app, we'll first create a file called "test" and note how long the request takes. And then we'll submit the following payload:
test1; ping -i 1 -c 15 127.0.0.1
As you can see, it takes significantly longer to process the second request. This means there may be a command injection vulnerability, because the server is actually executing the "ping" command.
There are a lot of things one can do to be malicious with a command injection vulnerability like the one we found. For example, we can remove all of the files on this user's account.
X; rm -r *
Defending Against Command Injection
To protect against command injection, use safe APIs and libraries when possible instead of using "eval" or any type of direct or indirect OS commands and evaluation. Allowlist input whenever possible. And if there are no safe APIs to use then make sure to sanitize all input and remove characters that may be interpreted, like semicolons in the case of our cloud storage example. It is very difficult to sanitize characters correctly, which you will learn as you tackle more advanced web application security topics, so that should be used alone only as a last resort. All of these techniques should be used in conjunction with each other.
Now that we can see the impact of a Command Injection vulnerability, let's look at the code running in this sandbox to see how to protect against attackers.
In this demonstration, let's examine the code in Python.
As you can see on line 4 and line 17, the application is using both a "subprocess" and "OS dot system" command to list and create files. Lets change these to use the Python standard library, and try to re-exploit the app.
This has fixed the command injection vulnerability.