# Dirty Pipe

## Theory

In March 2022, a researcher named Max Kellerman publicly disclosed a **Linux Kernel vulnerability** (nicknamed "Dirty Pipe" for its similarities to the notorious "[Dirty Cow](/redteam/privilege-escalation/linux/kernel-exploits/dirtycow.md)" exploit affecting older versions of the kernel) that allowed attackers to arbitrarily overwrite files on the operating system. Arbitrary file overwrites at the kernel level can be very easily leveraged to **escalate privileges** on the machine

The vulnerability arises because of how the kernel implements "pipes": the Linux kernel provides a system call called "`splice()`", which is effectively a shortcut designed to speed up the process of pushing the contents of a file into a pipe. This optimisation is achieved by moving *references* to the pages storing the file contents, rather than moving the entirety of the data. In other words, `splice()` allows us to point a pipe at a page which is already loaded into memory, containing a section of a file originally opened by a process requesting read-only access.

It's not quite that simple, however; we are still missing one final piece of the puzzle. *Usually* when you write to a pipe after splicing a file, a new `pipe_buffer` is created to avoid overwriting the spliced data. So, how do we force the kernel to allow us to overwrite the relevant page(s)?

This is the real crux of the vulnerability, and it can all be traced back to two commits in the Linux kernel:

* A bug was introduced in [Linux Kernel v4.9 (2016)](https://github.com/torvalds/linux/commit/241699cd72a8489c9446ae3910ddd243e9b9061b) which allowed pipes to be created with arbitrary flags. None of the flags available at the time were in any way dangerous, so this wasn't an issue, until...
* [Linux Kernel v5.8 (2020)](https://github.com/torvalds/linux/commit/f6dd975583bd8ce088400648fd9819e4691c8958) added a new flag — `PIPE_BUF_FLAG_CAN_MERGE`. In simple terms, this flag tells the kernel that the page can be updated without forcing a rewrite of the data.

To summarise: we have a flag that allows us to tell the kernel that it's okay to overwrite the data in a page, we have a bug that allows us to specify arbitrary flags for a pipe, and we have a system call that inadvertently allows us to point pipes at page buffers which were opened as read-only. What could possibly go wrong?

Put simply, the exploit first opens a target file with the read-only flag set — in order to do this, we must choose a file that we have permission to read. The exploit then prepares a pipe in a special way, forcing the addition of the `PIPE_BUF_FLAG_CAN_MERGE` flag. Next, it uses `splice()` to make the pipe point at the desired section of the target file. Finally, it writes whatever arbitrary data that the user has specified into the pipe, overwriting the target page by merit of the `PIPE_BUF_FLAG_CAN_MERGE` flag.

## Practice

{% tabs %}
{% tab title="Enumerate" %}
The vulnerability **has been patched in Linux kernel versions 5.16.11, 5.15.25 and 5.10.102,** and Linux kernel versions newer than **5.8 are affected**.

```bash
#Get Kernel version
$ uname -r
5.8.0-1035-aws
```

If you are not sure if a target system is vulnerable you may use this [bash scripts](https://github.com/basharkey/CVE-2022-0847-dirty-pipe-checker) developed by basharkey.

```bash
# Check for current kernel version
./dpipe.sh

# Check for specific kernel version
./dpipe.sh 5.10.11
```

{% endtab %}

{% tab title="Exploit" %}
Using [these exploits](https://github.com/AlexisAhmed/CVE-2022-0847-DirtyPipe-Exploits) from AlexisAhmed, we can abuse CVE-2022-0847

```bash
#Compile
https://github.com/AlexisAhmed/CVE-2022-0847-DirtyPipe-Exploits
chmod +x compile.sh
./compile.sh
```

The first exploit will replace the root password with the password "piped" and will take a backup of the /etc/passwd file under /tmp/passwd.bak. Furthermore, the exploit will also provide you with an elevated root shell and will restore the original passwd file when done.

```
./exploit-1
```

The second exploit can be used to inject and overwrite data in read-only SUID process memory that run as root.

```bash
#First, find SUID binaries
find / -perm -4000 2>/dev/null

#Exploit
./exploit-2 /usr/bin/sudo
```

{% hint style="info" %}
If the target doesn't have gcc installed, you may need to recreate a similar virtual environement to compile the exploit.
{% endhint %}
{% endtab %}
{% endtabs %}

## Resources

{% embed url="<https://tryhackme.com/room/dirtypipe>" %}

{% embed url="<https://dirtypipe.cm4all.com/>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://red.infiltr8.io/redteam/privilege-escalation/linux/kernel-exploits/dirtypipe.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
