Turning Read to Write Permissions with Dirty Pipe 
T

Post Credit: Austin Miller

Another Linux vulnerability has been uncovered, this time giving users the chance to write arbitrary data to files without permissions. Although relatively difficult to exploit, this is vulnerability could be easily weaponized by an insider threat. In a time where the adversary is turning to corrupting insiders, this is very much a red alert scare for organizations that depend on Linux services. 

What is Dirty Pipe?

Exploiting a fundamental way in which Linux deals with memory and file handling, Dirty Pipe is a vulnerability that was caused by commit 241699cd72a8 (made in 2016) that added new functionality to pipe buffers. To understand how this vulnerability was possible, we need to look at five key aspects of the way Linux handles memory: memory pages, page caches, pipes, pipe flags, and system calls. 

Memory pages 

The CPU handles memory as memory pages. These are usually around 4KB in size. 

Page caches 

The kernel has a subsystem called page cache which handles all memory pages. After a file has been read, it is passed over to the page cache to stop the excessive disk access on further reading. When a file is written, it is also passed to the page cache before being properly stored in the actual storage device. 

Here is where the exploit starts – due to the way that the data is passed, it can be accessed again when it is in the cache. This has been known as dirty in the past, most notably with the Dirty Cow vulnerability. If the adversary can access the cache, they can write arbitrary code to the system. Now, let’s talk about pipes… 

Pipes 

Data channels that handle communications between Linux processes are called pipes. Every time something is written to a pipe, the OS allocates a page to it. 

Sometimes, writing files may not fill the full 4KB that a page is capable of storing. In these cases, the write is added to the existing page instead of starting a new one. This is called an anonymous pipe buffer. 

Pipe flags 

To show the status and permissions of all data in the pipe, a flag is used. There are many kinds of flags that are used with Linux pipes, but the most interesting one for this case is the PIPE_BUF_FLAG_CAN_MERGE flag – this shows that the anonymous pipe buffer can be merged with another page. 

System calls 

When user needs to communicate with the kernel, they use system calls (or syscalls). With Linux 2.6.16 came the new form of syscall, named splice(). This allows the movement of data from file descriptors and pipes without the user interacting with the system. 

How can the Dirty Pipe vulnerability be exploited? 

To test out this vulnerability, I am using the exploit created by AlexisAhmed on GitHub. You can try it out yourself (on your own systems!) here. I tested this out on Ubuntu 20.4.3, but you can try it on any Linux distro that has not been patched so far (see below to find out before details about patching). 

From an unprivileged user account, I used a scanner to check my install was vulnerable. 

The exploit linked above comes with two exploits. I will be carrying out exploit 1, which aims to make a backup of the /etc/passwd file and put it into a temporary directory. It will then change the root password in the file, giving you access to an elevated shell. After loading the exploit and compiling the files, you should see this:

At this point, the attacker has root privileges. The potential for further exploits from this point is enormous and has been explored in more detailed by Max Kellerman in his original documentation

By writing arbitrary code to the /etc/passwd file, the attacker has gained root access to the system with an elevated shell. The PIPE_BUF_FLAG_CAN_MERGE functionality lets the adversary add data through the pipe to the files of their choice, potentially leading to catastrophic levels of malicious activity on your network. 

How can I defend my systems against Dirty Pipe exploits? 

For people running software that relies on the Linux kernel, the following versions have been patched to stop the vulnerability from being exploited: 

  • 5.16.11 
  • 5.15.25 
  • 5.10.102 

If you are using a version of Linux from 5.8 to 5.10 (5.10.102 not inclusive), you will need to update your systems. Google has also announced that the Android code base has been updated. 

Despite some major distros being behind the curve on updating the Linux kernel, RedHat has now released patches for their products. You may find that your chosen distro is still vulnerable to exploitation but check the appropriate security pages for the latest patches. 

If you need a scanner to check for systems that are vulnerable on your network, check out this free DirtyPipe scanner available on GitHub. 

Stay up to date with the latest threats

Our newsletter is packed with analysis of trending threats and attacks, practical tutorials, hands-on labs, and actionable content. No spam. No jibber jabber.