Command injection
OWASP
OWASP Web Security Testing Guide 4.2 > 7. Data Validation Testing > 7.12. Testing for Command Injection
ID | Link to Hackinglife | Link to OWASP | Description |
---|---|---|---|
7.12 | WSTG-INPV-12 | Testing for Command Injection | - Identify and assess the command injection points with special characters (i.e.: | ; & $ > < ' !) For example: ?doc=Doc1.pdf+|+Dir c:| |
Command injection vulnerabilities in the context of web application penetration testing occur when an attacker can manipulate the input fields of a web application in a way that allows them to execute arbitrary operating system commands on the underlying server. This type of vulnerability is a serious security risk because it can lead to unauthorized access, data theft, and full compromise of the web server.
Causes:
- User Input Handling: Web applications often take user input through forms, query parameters, or other means.
- Lack of Input Sanitization: Insecurely coded applications may fail to properly validate, sanitize, or escape user inputs before using them in system commands.
- Injection Points: Attackers identify injection points, such as input fields or URL query parameters, where they can insert malicious commands.
Impact:
- Unauthorized Execution: Attackers can execute arbitrary commands with the privileges of the web server process. This can lead to unauthorized data access, code execution, or system compromise.
- Data Exfiltration: Attackers can exfiltrate sensitive data, such as database content, files, or system configurations.
- System Manipulation: Attackers may manipulate the server, installmalware, or create backdoors for future access.
Types of injections:
Injection | Description |
---|---|
OS Command Injection | Occurs when user input is directly used as part of an OS command. |
Code Injection | Occurs when user input is directly within a function that evaluates code. |
SQL Injections | Occurs when user input is directly used as part of an SQL query. |
Cross-Site Scripting/HTML Injection | Occurs when exact user input is displayed on a web page. |
There are many other types of injections other than the above, like LDAP injection
, NoSQL Injection
, HTTP Header Injection
, XPath Injection
, IMAP Injection
, ORM Injection
, and others.
How to Test
Malicious Input: Attackers craft input that includes special characters, like semicolons, pipes, backticks, and other shell metacharacters, to break out of the intended input context and inject their commands. Command Execution: When the application processes the attacker's input, it constructs a shell command using the malicious input. The server, believing the command to be legitimate, executes it in the underlying operating system
Case Study: Perl
When viewing a file in a web application, the filename is often shown in the URL. Perl allows piping data from a process into an open statement. The user can simply append the Pipe symbol | onto the end of the filename.
PHP code injection
PHP code injection vulnerabilities, also known as PHP code execution vulnerabilities, occur when an attacker can inject and execute arbitrary PHP code within a web application. These vulnerabilities are a serious security concern because they allow attackers to gain unauthorized access to the server, execute malicious actions, and potentially compromise the entire web application.
Malicious Input: Attackers craft input that includes PHP code snippets, often enclosed within PHP tags (<?php ... ?>) or backticks (`).
Code Execution: When the application processes the attacker's input, it includes the injected PHP code as part of a PHP script that is executed on the server.
This allows the attacker to run arbitrary PHP code in the context of the web application.
Command injection: Appending a semicolon to the end of a URL for a .PHP page followed by an operating system command, will execute the command. %3B is URL encoded and decodes to semicolon
Special characters for command injection
The following special character can be used for command injection such as:
Injection Operator | Injection Character | URL-Encoded Character | Executed Command |
---|---|---|---|
Semicolon | ; |
%3b |
Both |
New Line | \n |
%0a |
Both |
Background | & |
%26 |
Both (second output generally shown first) |
Pipe | \| |
%7c |
Both (only second output is shown) |
AND | && |
%26%26 |
Both (only if first succeeds) |
OR | \| |
%7c%7c |
Second (only if first fails) |
Sub-Shell | `` |
%60%60 |
Both (Linux-only) |
Sub-Shell | $() |
%24%28%29 |
Both (Linux-only) |
Tip: In addition to the above, there are a few unix-only operators, that would work on Linux and macOS, but would not work on Windows, such as wrapping our injected command with double backticks (
``
) or with a sub-shell operator ($()
).
Injection Type | Operators |
---|---|
SQL Injection | ' , ; -- /* */ |
Command Injection | ; && |
LDAP Injection | * ( ) & \| |
XPath Injection | ' or and not substring concat count |
OS Command Injection | ; & \| |
Code Injection | ' ; -- /* */ $() ${} #{} %{} ^ |
Directory Traversal/File Path Traversal | ../ ..\\ %00 |
Object Injection | ; & \| |
XQuery Injection | ' ; -- /* */ |
Shellcode Injection | \x \u %u %n |
Header Injection | \n \r\n \t %0d %0a %09 |
Bypassing techniques for filters and WAFs
A web application may have a list of blacklisted characters, and if the command contains them, it would deny the request. The PHP
code may look something like the following:
Common tricks
Using environmental variables to substitute filtered characters in Linux
Slashes and back-slashes
A very commonly blacklisted character is the slash (/
) or backslash (\
) character, as it is necessary to specify directories in Linux or Windows. we can replace slashes (or any other character
) is through Linux Environment Variables
.
The $PATH
environment variable in Linux, for example, contains the /
character in a fixed position:
We can do the same with the $HOME
or $PWD
environment variables as well.
Semicolon
Following the same reasoning, this command gives you a semi-colon:
Other characters
Example:
Using environmental variables to substitute filtered characters in Windows
In a cmd session:
We can achieve the same thing using the same variables in Windows PowerShell
:
Character Shifting
There are other techniques to produce the required characters without using them, like shifting characters
.
We can use PowerShell commands to achieve the same result in Windows, though they can be quite longer than the Linux ones.
Bypassing Blacklisted Commands by inserting characters
A common bypass is Inserting certain characters within our command that are usually ignored by command shells like Bash or PowerShell
The important things to remember are that we cannot mix types of quotes and the number of quotes must be even.
Linux only
We can insert a few other Linux-only characters in the middle of commands, and the bash
shell would ignore them and execute the command.
Windows only
There are also some Windows-only characters we can insert in the middle of commands that do not affect the outcome, like a caret (^
) character, as we can see in the following example:
Case manipulation
One command obfuscation technique we can use is case manipulation, like inverting the character cases of a command (e.g. WHOAMI
) or alternating between cases (e.g. WhOaMi
).
However, when it comes to Linux and a bash shell, which are case-sensitive, as mentioned earlier, we have to get a bit creative and find a command that turns the command into an all-lowercase word. One working command we can use is the following:
There might be some issues with the above payload. Blank spaces can be filtered. To bypass it, we will change the blank spaces for the TAB url encoded characters %09
:
There are many other commands we may use for the same purpose, like the following:
Reverse commands
Another command obfuscation technique we will discuss is reversing commands and having a command template that switches them back and executes them in real-time. In this case, we will be writing imaohw
instead of whoami
to avoid triggering the blacklisted command.
The same can be applied in Windows.
We can first reverse a string, as follows:
Encoded commands
We can utilize various encoding tools, like base64
(for b64 encoding) or xxd
(for hex encoding). Let's take base64
as an example. First, we'll encode the payload we want to execute (which includes filtered characters):
We use the same technique with Windows as well. First, we need to base64 encode our string, as follows:
We may also achieve the same thing on Linux, but we would have to convert the string from utf-8
to utf-16
before we base64
it, as follows:
Finally, we can decode the b64 string and execute it with a PowerShell sub-shell (iex "$()"
), as follows:
In addition to the techniques we discussed, we can utilize numerous other methods, like wildcards, regex, output redirection, integer expansion, and many others. We can find some such techniques on PayloadsAllTheThings.
Code Review Dangerous API
Be aware of the uses of following API as it may introduce the command injection risks.
Java
C/C++
Python
PHP
Tools for evasion
Linux (Bashfuscator)
Installation:
Basic usage:
DOSfuscation
Installation:
Basic commands
Prevention
System commands
Instead of using system command execution functions, we should use built-in functions that perform the needed functionality, as back-end languages usually have secure implementations of these types of functionalities. For example, suppose we wanted to test whether a particular host is alive with PHP
. In that case, we may use the fsockopen
function instead, which should not be exploitable to execute arbitrary system commands.
Input Validation
Input validation should be done both on the front-end and on the back-end. Whether using built-in functions or system command execution functions, we should always validate and then sanitize the user input. Input validation is done to ensure it matches the expected format for the input, such that the request is denied if it does not match.
PHP
In PHP
, like many other web development languages, there are built in filters for a variety of standard formats, like emails, URLs, and even IPs, which can be used with the filter_var
function, as follows:
Code: php
Javascript in NodeJS
If we wanted to validate a different non-standard format, then we can use a Regular Expression regex
with the preg_match
function. The same can be achieved with JavaScript
for both the front-end and back-end (i.e. NodeJS
), as follows:
Just like PHP
, with NodeJS
, we can also use libraries to validate various standard formats, like is-ip for example, which we can install with npm
, and then use the isIp(ip)
function in our code. You can read the manuals of other languages, like .NET or Java, to find out how to validate user input on each respective language.
Input Sanitization
Removing any non-necessary special characters from the user input. Input sanitization is always performed after input validation.
PHP
Case: IP
We can use preg_replace
to remove any special characters from the user input, as follows:
As we can see, the above regex only allows alphanumerical characters (A-Za-z0-9
) and allows a dot character (.
) as required for IPs.
Javascript
We can also use the DOMPurify library for a NodeJS back-end, as follows:
Server Configuration
- Use the web server's built-in Web Application Firewall (e.g., in Apache
mod_security
), in addition to an external WAF (e.g.Cloudflare
,Fortinet
,Imperva
.. - Abide by the Principle of Least Privilege (PoLP) by running the web server as a low privileged user (e.g.
www-data
) - Prevent certain functions from being executed by the web server (e.g., in PHP
disable_functions=system,...
) - Limit the scope accessible by the web application to its folder (e.g. in PHP
open_basedir = '/var/www/html'
) - Reject double-encoded requests and non-ASCII characters in URLs
- Avoid the use of sensitive/outdated libraries and modules (e.g. PHP CGI)