Command Injection

Command Injection

Introduction (What is Command Injection?)

In this section, we'll explore the web vulnerability known as command injection. We'll learn about its nature, understand its impact, and the risks it poses to applications.

Subsequently, you'll have the opportunity to apply this knowledge practically by:

  • Discovering the command injection vulnerability.

  • Testing and exploiting the vulnerability using payloads tailored for different operating systems.

  • Implementing preventive measures to address this vulnerability in an application.

  • Finally, you'll be able to put theory into practice with a practical exercise at the end of the module.

To start, let's grasp the concept of command injection. This vulnerability involves exploiting an application's behavior to execute OS commands, utilizing the application's privileges. For instance, if a web server runs as a user named "joe," command injection can execute commands under the "joe" user, granting access to joe's permissions.

Command injection is commonly referred to as "Remote Code Execution" (RCE) due to its capability to execute code remotely within an application. These vulnerabilities are highly attractive to attackers as they enable direct interaction with the vulnerable system. For instance, an attacker can access system or user files, data, and other sensitive information.

For example, being able to abuse an application to perform the command whoami to list what user account the application is running will be an example of command injection.

Command injection ranked among the top ten reported vulnerabilities in Contrast Security's AppSec intelligence report (Contrast Security AppSec., 2019). Additionally, OWASP consistently highlights such vulnerabilities as one of the top ten threats to web applications (OWASP framework).

Discovering Command Injection

This vulnerability arises due to applications utilizing functions in programming languages like PHP, Python, and NodeJS to transfer data and execute system calls on the machine's operating system. For instance, taking input from a field and searching for an entry in a file. Consider the following code snippet as an example:

In the code snippet, the application takes user-entered data from an input field named $title to search for a song title in a directory. Let's break this down into a few simple steps.

  1. The application stores MP3 files in a directory on the operating system.

  2. The user inputs the desired song title, saved in the $title variable.

  3. The data within this $title variable is passed to the command grep to search a text file named songtitle.txt for the entry of whatever the user wishes to search for.

  4. The application's response to the search output of songtitle.txt determines whether the song exists or not for the user.

This information would typically be stored in a database. however, this is just an illustration of where an application takes input from a user to interact with the application’s operating system.

An attacker could exploit this application by injecting their commands for execution. Instead of using grep to search songtitle.txt, they could request the application to read data from a more sensitive file.

Exploiting applications in this manner remains possible regardless of the programming language they use. As long as the application processes and executes user input, the risk of command injection exists. For instance, the code snippet below represents an application written in Python.

Note that you are not required to understand the syntax of these applications. However, for clarity, let me outline the steps of how this Python application works:

  1. The "flask" package is utilized to set up a web server.

  2. A function uses the "subprocess" package to execute a command on the device.

  3. A route is defined in the web server that will execute whatever command is provided. For instance, to execute whoami, one would visit http://flaskapp.thm/whoami.

Exploiting Command Injection

You can often determine whether or not command injection may occur by the behavior's of an application, as you will come to see in the practical session of this room.

Applications that incorporate user input to populate system commands can lead to unintended behavior. For instance, the usage of shell operators such as ; , &, and && can combine multiple system commands and execute them simultaneously.

Command Injection can be detected in mostly one of two ways:

  1. Blind command injection

  2. Verbose command injection

I have outlined these two methods in the table below, and the following sections will provide a more detailed explanation:

MethodDescription
BlindThis type of injection is where there is no direct output from the application when testing payloads. Determining the success of your payload requires investigating the application's behaviors carefully.
VerboseThis type of injection is where there is direct feedback from the application once you test a payload. For instance, running the whoami command to see the user the application is running under will result in the web application outputting the username directly on the page.

Detecting Blind Command Injection

Blind command injection is when command injection occurs; however, there is no output visible, so it is not immediately noticeable. For example, a command is executed, but the web application outputs no message.

For this type of command injection, we will need to use payloads that introduce a time delay. For instance, using the ping and sleep commands can be effective. With ping, the application will hang for x seconds based on the number of pings you specify, showcasing the time delay effect.

Another method of detecting blind command injection is by forcing some output. This can be done by using redirection operators such as >. For example, we can tell the web application to execute commands such as whoami and redirect that to a file. We can then use a command such as cat to read this newly created file’s contents.

Testing command injection this way can be complex and requires significant experimentation, especially considering that the syntax for commands varies between Linux and Windows systems.

The curl command is an excellent method to test for command injection as it allows you to deliver data to and from an application within your payload. For example, a simple curl payload to an application is possible for command injection, as shown in the code snippet below.
curl http://vulnerable.app/process.php%3Fsearch%3DThe%20Beatles%3B%20whoami

Detecting Verbose Command Injection

Detecting command injection using verbose feedback is arguably the easier method of the two. Verbose command injection occurs when the application provides feedback or output regarding what is happening or being executed.

For example, the output of commands such as ping or whoami is directly displayed on the web application.

Useful payloads

I have compiled some useful payloads for both Linux and Windows in the tables below.

Linux
PayloadDescription
whoamiSee what user the application is running under.
lsList the contents of the current directory. You might discover files like configuration files, environment files (tokens and application keys), and other valuable information.
pingThis command will cause the application to hang, making it useful for testing an application for blind command injection.
sleepThis payload is also useful for testing an application for blind command injection when the machine does not have ping installed.
ncNetcat can be utilized to spawn a reverse shell onto the vulnerable application, providing a foothold to explore the target machine for other services, files, or potential privilege escalation.
Windows
PayloadDescription
whoamiSee what user the application is running under.
dirExecute the command to list the contents of the current directory, potentially revealing valuable files like configuration files, environment files (tokens and application keys), and more.
pingThis command will cause the application to hang, making it useful for testing an application for blind command injection.
timeoutThis command will also invoke the application to hang. It is also useful for testing an application for blind command injection if the ping command is not installed.

Remediating Command Injection

Command injection can be prevented through various methods, including limiting the usage of potentially dangerous functions or libraries in a programming language and implementing input filtering independently from user input. Although the examples provided are in PHP, these principles are applicable to many other programming languages.

Vulnerable Function

In PHP, several functions interact with the operating system to execute commands via the shell. Some of these functions include:

  • Exec

  • Passthru

  • System

Take this snippet below as an example. Here, the application will only accept and process numbers that are inputted into the form. This means that any commands such as whoami will not be processed.

The application will only accept a specific pattern of characters (the digits 0-9), and it will then only proceed to execute this data, which is all numerical.

These functions take input, such as a string or user data, and will execute whatever is provided on the system. Any application that uses these functions without proper checks will be vulnerable to command injection.

Input Sanitization

Sanitizing any user input that an application uses is an effective method to prevent command injection. This involves specifying the formats or types of data that a user can submit. For instance, an input field that only accepts numerical data or removes any special characters such as >, &, and /.

In the snippet below, the PHP function filter_input is used to check whether any data submitted via an input form is a number or not. If it is not a number, the input is considered invalid.

Bypassing Filters

Applications will use various techniques to filter and sanitize data from a user's input, which may restrict specific payloads. However, we can abuse the logic behind an application to bypass these filters. For instance, if an application strips out quotation marks, we can use their hexadecimal value to achieve the same result.

When executed, even though the given data is in a different format than expected, it can still be interpreted and yield the same result.

Practical: Command Injection

Command Injection Payload

Conclusion

To sum up, we've explored discovering the command injection vulnerability, testing and exploiting it with various payloads for different operating systems, prevention methods, and practical application of the learning through performing command injection.