Skip to main content
  1. Blog Posts/

OS Command Injection

··920 words·5 mins

Guide 07 in Sarah’s Welcome to Web Security Series #

In this series, Sarah discusses some common vulnerability classes found in web security and how you can find and exploit them. Today’s focus is OS command injection, which allows an attacker to inject code directly into a system shell.

Introduction #

As one might expect, OS command injection, sometimes called shell injection, is a vulnerability that allows an attacker to send data to a system shell. The consequences of this attack can vary, as the scope can be limited by the privileges of the target application. However, it is possible for an attacker to exfiltrate sensitive data, install further malicious software or compromise the entire system using an OS command injection attack.

Finding OS Command Injection Vulnerabilities #

For a vulnerability that can lead to total system compromise, OS command injection vulnerabilities are surprisingly common. This is largely due to the fact that such vulnerabilities arise from insufficient input validation, which can be difficult to make completely secure.

Moreover, OS command injection vulnerabilities can be possible anywhere user input is passed into a system shell (and improperly validated). This could be through a form, session cookies, HTTP headers, etc. For each possible entry point, an attacker has to guess at how the user input is being processed. Some questions that can guide this process are:

  • What does the original function do?
    • Return data, modify data, add data, etc
  • How many arguments does the original function expect?
  • Is there any form of validation or sanitation that can be bypassed?

Once an attacker has a rough idea of how the data is processed, a simple payload can be crafted to test it. For example, if there was a system that simply printed the contents of a requested file, a simple test would be to add an ampersand (&) and a new command (e.g. ls) to the expected input (e.g. file.txt). The ampersand is a shell command separator, meaning that the shell will execute each command one after another. If the system is vulnerable to OS command injection, then it should return the content of file.txt and then list everything else in the directory.

Exploiting OS Command Injection Vulnerabilities #

Once you have confirmed that the system is vulnerable to OS command injection, then the next step is to exploit it by injecting a suitable payload. The appropriate payload will naturally be determined by what you want to do. For a simple proof of concept, using a simple command like echo or even ping is often enough. However, in cases where you wish to discover more about the system, commands like whoami, ifconfig or ps (and their Windows equivalents) may be more appropriate. In either case, to actually inject the payload, you will need to find some way to manipulate the original command. As seen in the discovery stage, command operators like &, &&, | or || can be used to inject the desired payload. These separators work on both Unix and Windows systems.

Consider some online scoreboard for a browser-based game that (for some reason) has to use a shell command to retrieve a player’s score. If a player wanted to check their score, they would have to visit a page and enter their playerID. The playerID might then be taken as an argument by some shell command:

scoreboardSystem.pl 1337

The command would then return the score for the specified player and then return that to the user. However, if we assume that this website has no defences, we can inject a command into the system by using the & operator. Rather than entering just our playerID, we might instead enter 1337 & echo get_pwned. When this is received by the system it will execute the original command and then our echo command, yielding the following output for example:

9001
get_pwned

This would be enough to demonstrate that the system is vulnerable to OS command injection.

Defending Against OS Command Injection #

As aforementioned, good user input validation is crucial to preventing OS command injection, though there are a few other ways to protect your system. The most obvious defence is simply to not call OS commands directly. Using libraries or APIs instead is generally the preferred method, though this is not always possible, depending on the language and system being used. Secondly, escape values can be added but there are ways this can be bypassed, so it should be used to enhance other defence mechanisms, rather than being one in and of itself. Some languages, such as PHP, have built-in methods to escape shell commands. Finally, parameterisation and input validation should be implemented and securely configured, if it is impossible to avoid using system commands that have user input. It is also considered good practice to give the relevant system only the lowest level of privilege it needs to perform its function and to segregate the accounts, based on the task they perform.

To see specific implementations with coded examples, check out OWASP’s cheat sheet.

Conclusion #

OS command injection is similar to its fellow code injection vulnerabilities, with the crucial distinction that it affects the default functionality of the application, rather than simply having code be executed by the application. This makes it a very dangerous exploit, given the potential damage it can cause and the difficulty in completely securing all potential entry points.

If you are interested in learning more about OS command injection and web security, the WebSecurity Academy is a fantastic resource. You can create a free account and explore their labs here.