Dirty Pipe: CVE-2022–0847 Tryhackme Writeup
||ROOM : DIRTYPIPE||
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” exploit affecting older versions of the kernel) that allowed attackers to arbitrarily overwrite files on the operating system. The vulnerability was responsibly disclosed in early 2022 and was publicly released in a blog post written by Max Kellerman soon after patches were made available.
Arbitrary file overwrites at the kernel level can be very easily leveraged to escalate privileges on the machine (i.e. to obtain administrator, or “root” privileges). This is a devastating vulnerability, made more so by its reach: any devices running a vulnerable version of the Linux kernel (including Android phones) are affected!
This room will provide an overview of the vulnerability, as well as give you an opportunity to exploit it for yourself in the vulnerable machine attached to this task. We will start by taking a look at the vulnerability and exploit at a high-level, before moving on to exploiting the vulnerability in subsequent sections of the room.
Without further ado, let’s begin.
IDEA ABOUT THE VULN:
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. See where this is going?
By splicing a page into the pipe then writing our own arbitrary data to the pipe, we can overwrite the contents of the page!
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, no changes actually happen on the disk. Changes are made to the page buffer (in memory), but nothing is permanently altered and the file itself remains unchanged. So, how do we force the kernel to write the contents of the relevant page(s) back to the disk?
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) 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) added a new flag —
PIPE_BUF_FLAG_CAN_MERGE. In simple terms, this flag tells the kernel that the changes written to the page pointed to by the pipe should be written directly back to the file that the page comes from.
To summarise: we have a flag that allows us to tell the kernel to write the page back to the disk as data comes into it, 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.
PRACTICAL APPROACH TO EXPLOIT:
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, thereby overwriting the page buffer and — by merit of
PIPE_BUF_FLAG_CAN_MERGE — overwriting the file on the disk.
Let’s get started then, we know have the idea on how the exploit works.
First get to the directory where the code is placed and then we know the exploit let’s us write a file which is readable by us. After knowing this we know we can make use of /etc/passwd to escalate our privilege.
Now to exploit this, we will create a hash to write in /etc/passwd and then use that known hash to login and escalate our privilege.
this is the format to put a entry in /etc/passwd.
This exploit can distructive for the system a little that’s why we will make a copy in the tmp folder.
cp /etc/passwd /tmp/passwd
now to change this we will have to get the line no. which will act as the offset to where the changes has to be made. Let’s get that by using grep.
grep -b “games” /etc/passwd
I don’t know why was i unable to copy it and paste the whole entry. I had to write everything which was such a drag.
./exploit /etc/passwd 189 ‘webhead:$6$THM$wl1hbXsCUQ0VrK9u7KxCyT37dVnWnHgEGUDXG2ZMDvyfI.yY82Guu67STt5VhILCrQDh..BNWk5.d3ao40meP.:0:0::/root:/bin/bash
as we can see we got the output It worked! means writing it was worth it. let’s try to su into my created account.
I forgot to use the right syntax while doing it on attack box coz I couldn’t copy anything there. so I used ssh to login and then try to do it and it worked fine
Here You Go With The ROOT flag.
THERE IS A BONUS TASK, Let’s Get Going then:
In the previous task, we exploited the Dirty Pipe vulnerability using Max Kellerman’s original proof of concept exploit code; however, other exploits have since been released. The original PoC allowed us to overwrite any file with arbitrary data at an offset of our choosing; however, other implementations have abused the arbitrary file write vulnerability in a variety of different ways.
To demonstrate this concept, a second exploit script has been added to the lab machine — this can be found on the target at
Bl4sty’s exploit capitalises on this. Instead of overwriting a file like
/etc/passwd, it overwrites a user-specified SUID binary (such as
/bin/su), injecting shellcode into it which then gets executed with the permissions of the privileged user (i.e.
root). Specifically, the exploit hijacks the chosen SUID binary and forces it to create a backdoor binary in
/tmp which has the SUID bit and calls
/bin/sh. It then restores the targeted SUID binary to full working order by re-adding the overwritten section, and uses the newly created backdoor to grant the attacker a shell as the privileged user.
This one was very easy but useful if we find this somewhere in a box.
THE ROOM IS DONE! Happy HACKING 🥸