Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@

This article describes how to test an application for OS command injection. The tester will try to inject an OS command through an HTTP request to the application.

OS command injection is a technique used via a web interface in order to execute OS commands on a web server. The user supplies operating system commands through a web interface in order to execute OS commands. Any web interface that is not properly sanitized is subject to this exploit. With the ability to execute OS commands, the user can upload malicious programs or even obtain passwords. OS command injection is preventable when security is emphasized during the design and development of applications.
OS commmand injection is a vulnerability that occurs when user input is directly passed to an operating system command without proper validation or sanitization. This allows the user to inject and execute arbitrary commands on the server which can lead to unauthorized data access, data corruption and full server compromise. This vulnerability can be prevented by emphasizing security during the design and development of applications.

## Test Objectives

- Identify and assess the command injection points.
- Identify and assess command injection points.
- Bypass special characters and OS commands filter.

## How to Test

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revert

Expand All @@ -36,7 +37,7 @@ Example:

### Example

Consider the case of an application that contains a set of documents that you can browse from the Internet. If you fire up a personal proxy (such as ZAP or Burp Suite), you can obtain a POST HTTP like the following (`https://www.example.com/public/doc`):
Consider the case of an application that contains a set of documents that you can browse from the internet. If you fire up a personal proxy (such as ZAP or Burp Suite), you can obtain a POST HTTP like the following (`https://www.example.com/public/doc`):

```txt
POST /public/doc HTTP/1.1
Expand Down Expand Up @@ -106,16 +107,105 @@ In this case, we have successfully performed an OS injection attack.

## Special Characters for Command Injection

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revert

The following special character can be used for command injection such as `|` `;` `&` `$` `>` `<` `'` `!`
Special characters are used to chain multiple commands together.
These characters will vary based on the operating system running on the web server.
For instance, the following special characters can be used on both Windows and Unix-based systems :

- `cmd1|cmd2` : Uses of `|` will make command 2 to be executed whether command 1 execution is successful or not.
- `cmd1;cmd2` : Uses of `;` will make command 2 to be executed whether command 1 execution is successful or not.
- `cmd1||cmd2` : Command 2 will only be executed if command 1 execution fails.
- `cmd1&&cmd2` : Command 2 will only be executed if command 1 execution succeeds.
- `$(cmd)` : For example, `echo $(whoami)` or `$(touch test.sh; echo 'ls' > test.sh)`
- `cmd` : It's used to execute a specific command. For example, `whoami`
- `>(cmd)`: `>(ls)`
- `<(cmd)`: `<(ls)`
- `cmd1|cmd2` : cmd2 will be executed whether cmd1 succeeds or not.
- `cmd1||cmd2` : cmd2 will only be executed if cmd1 fails.
- `cmd1&&cmd2` : cmd2 will only be executed if cmd1 succeeds.
- `cmd1&cmd2` : cmd2 will be executed whether cmd1 succeeds or not.

Note that, `;` will work on Unix-based systems and PowerShell. However, it will not work on Windows Command Prompt (CMD).
Furthermore, you can use Bash command substitution `$(cmd)` or &grave;`cmd`&grave; to execute commands on Unix-based systems.
Additionally, Linux file descriptors such as `>(cmd)`, `<(cmd)` can also be used.

## Filter Evasion

To prevent OS command injection, web developers often use filters. However, these filters are sometimes not properly implemented which allows attackers to bypass them.
In this section, we will cover different techniques used to bypass those filters.

### Methodology

First of all, it is always good practice to have a basic understanding of how the filter works before trying to bypass it.
Here is a methodology we can use when we come across a filter:

- Is the filter client-side or server-side ?
- Is the filter applied on special characters, OS commands, or both ?
- Is the webapp using a allowlist or blocklist filter ?
- What OS is running on the web server? This allows us to have an idea of the commands and special characters we can use.

### Special Characters Filter Evasion

As previously mentionned, filters can either be applied on special characters, OS commands or both.
To bypass filters applied on special characters, we can use environment variables, Bash brace expansion or URL encoding.

#### URL Encoding

URL encoding special characters can allow us to bypass the filter if the web server only blocks the plaintext special characters.
Here are some special characters with their URL encoded format:

|Special Character|URL Encoding|
|-----------------|------------|
|; | %3b |
|space | %20 |
|tab | %09 |
|& | %26 |
|New line | %0a |

For instance, instead of using `;whoami`, we could use `%3bwhoami`.

#### Environment Variables

Special characters like space, semi-colon, tab, or new line will generally be filtered by the web server especially if they are not useful for the specified input.
To escape this restriction, we can use environment variables such as **IFS**, **PATH** or **LS_COLORS** in Linux and **HOMEPATH** in Windows.
For instance, on Linux, `/`, `;` and `[space]` can be replaced respectively with `${PATH:0:1}`, `${LS_COLORS:10:1}`, and `${IFS}`.
On Windows CMD, we can replace `\` with `%HOMEPATH:~6,1%`, or use `$env:HOMEPATH[0]` in PowerShell.

#### Bash Brace Expansion

Bash brace expansion is a Bash feature that allows you to execute commands by using curly braces.
For example, `{ls,-la}` will execute `ls -la` command. This can be extremely useful if the web server is filtering space, new line, or tab characters.
Let's assume that we want to display the content of '/etc/passwd' file. Thus, instead of using `;cat /etc/passwd`, we can use `;{cat,/etc/passwd}`.
That said, it's important to note that this technique will only work if the web server is using Bash and if characters like `}{/,;` are not filtered.

### Commands Filter Evasion

In this section, we are going to explore some techniques used to bypass filters applied on operating system commands.

#### Case Modification

Case modification is a technique that can be used to bypass OS command filters. This could be handy if the filter used by the server is case sensitive.
However, note that this will generally work on Windows systems see that commands are case sensitive on Linux.
For instance, if we notice that the web server is blocking `;whoami`, we can try to use `;WhoAmi`.
To use uppercase commands on Linux, we can use a technique called **character shifting** that works as follows:
`;$(tr "[A-Z]" "[a-z]"<<<"WhoaMi")`
The command above will simply translate each uppercase character to its corresponding lowercase character.

#### Character Insertion

Characters like `\`; `$@`, `'` can be inserted into Linux OS commands without affecting the normal execution of the command.
For example, `who\ami`, `w$@hoami` or `wh'o'ami` will all execute the `whoami` command

Note that the number of single quotes `'` in the Linux command must be **even**, otherwise you will get an error. If you're using Windows CMD, make sure to use double quotes `"` instead.
Furthermore, you can also use a caret `^` in CMD commands. For example, `whoa^mi` will execute the `whoami` command. This does not work in PowerShell.

#### Base64 Encoding

In certain scenarios, the web server may filter commands such as `whoami`, `id`, etc.
Let's suppose that `whoami` is blocked by the web server. Therefore, we cannot use a payload like `;whoami`.
To bypass this restriction, we will use the base64 encoded format of `whoami` by executing: `echo -n 'whoami' | base64`. This will return `d2hvYW1p`.
After that, we will send the following payload: `;bash<<<$(base64 -d<<< d2hvYW1p)` in the vulnerable parameter. This should then bypass the server-side filter and allow us to achieve remote command execution.

**Finally, note that you may need to combine different special characters and OS command filter evasion techniques to successfully bypass the filters put it place by the web server.**

## Blind Command Injection

Sometimes, we may not be able to see the output from our injected command in the web server's HTTP response. Thus, we will need to find a way to confirm whether or not our injection succeeded. To do that, we can use `HTTP`, `DNS`, or `SMTP` remote servers under our control.
We can also use **time delay system commands** like `sleep` (Linux), `timeout` (Windows), or network utility like `ping`.
For instance, we can execute `;sleep(5)` and if the web server waits 5 seconds before sending a response back to us, we can confirm that it is vulnerable to a blind command injection.
Moreover, we can also **redirect the output of the injected command in the web server's web root**. `;whoami>/var/www/html/poc.txt;`
After that, we can execute `curl http://website.com/poc.txt`. If we are able to retrieve the file, we can then confirm that the web server is vulnerable to a blind command injection.

## Code Review Dangerous API

Expand Down Expand Up @@ -147,17 +237,23 @@ Be aware of the uses of following API as it may introduce the command injection
- `exec`
- `proc_open`
- `eval`
- `passthru`

## Remediation

### Sanitization

The URL and form data needs to be sanitized for invalid characters. A deny list of characters is an option but it may be difficult to think of all of the characters to validate against. Also there may be some that were not discovered as of yet. An allow list containing only allowable characters or command list should be created to validate the user input. Characters that were missed, as well as undiscovered threats, should be eliminated by this list.
The URL query parameters and form data need to be validated and sanitized to prevent the injection of malicious characters.
A blocklist of characters is an option but it may be difficult to think of all of the characters to validate against. Also there may be some that were not discovered as of yet.
A allowlist containing only authorized characters or commands should be created to validate the user input. Characters that were missed, as well as undiscovered threats, should be eliminated by this list.

General deny list to be included for command injection can be `|` `;` `&` `$` `>` `<` `'` `\` `!` `>>` `#`

Escape or filter special characters for windows, `(` `)` `<` `>` `&` `*` `‘` `|` `=` `?` `;` `[` `]` `^` `~` `!` `.` `"` `%` `@` `/` `\` `:` `+` `,` ``` ` ```

General deny list to be included for command injection can be `|` `;` `&` `$` `>` `<` `'` `\` `!` `>>` `#`
Escape or filter special characters for Linux, `{` `}` `(` `)` `>` `<` `&` `*` `‘` `|` `=` `?` `;` `[` `]` `$` `` `#` `~` `!` `.` `"` `%`  `/` `\` `:` `+` `,` ``` ` ```

Escape or filter special characters for windows,   `(` `)` `<` `>` `&` `*` `‘` `|` `=` `?` `;` `[` `]` `^` `~` `!` `.` `"` `%` `@` `/` `\` `:` `+` `,` ``` ` ```
Escape or filter special characters for Linux, `{` `}` `(` `)` `>` `<` `&` `*` `‘` `|` `=` `?` `;` `[` `]` `$` `–` `#` `~` `!` `.` `"` `%`  `/` `\` `:` `+` `,` ``` ` ```
Moreover, avoid using functions that execute operating system commands in your application unless absolutely necessary. For instance, instead of using `system("cp /path/to/file1.txt /path/to/file2.txt")` to copy a file, you can directly use the php built-in function `copy("cp /path/to/file1.txt, /path/to/file2.txt")` which does exactly the same thing.

### Permissions

Expand All @@ -167,6 +263,8 @@ The web application and its components should be running under strict permission

- OWASP [WebGoat](https://owasp.org/www-project-webgoat/)
- [Commix](https://github.com/commixproject/commix)
- [Invoke-DOSfuscation](https://github.com/danielbohannon/Invoke-DOSfuscation)
- [Bashfuscator](https://github.com/Bashfuscator/Bashfuscator)

## References

Expand Down