Kernel exploitation is becoming much more popular among exploit writers and attackers. Playing with the heart of the operating system can be a dangerous game. Kernel exploits require both art and science to achieve. Every OS has its quirks and so every exploit must be molded to fully exploit its target. This blog covers just one of these exploits, whimsically entitled Dirty Cow.[1]
What is it?
Copy-on-write or CoW is a technique to efficiently copy data resources in a computer system. If a unit of data is copied but not modified, the “copy” can exist as a reference to the original data. Only when the copied data is modified, a copy is created, and new bytes are actually written. In short, when a process requests a copy of some data (e.g., a file), the kernel does not create the actual copy until it’s being written into.
Dirty COW (Dirty copy-on-write) is a vulnerability that affects all versions of the Linux kernel since version 2.6.22, which was released in 2007. It is listed in the Common Vulnerabilities and Exposures as CVE-2016-5195. It was discovered in 2016 and fully patched in 2017. At the moment of discovery, everyone using a Linux based system was susceptible to the exploit.
How does it work?
Dirty COW allows processes to write to read-only files. This exploit makes use of a race condition that lives inside the kernel function which handles the copy-on-write feature of memory mappings. A race condition occurs when two or more process threads can access shared data and they try to change it at the same time. An example use case of the exploit includes over-writing a user’s UID in /etc/passwd
to gain root privileges.
For a more detailed and a very fun visual explanation of the Dirty COW vulnerability, check out this page!
Example
To test out Dirty COW yourself, all you need is a vulnerable environment and the malicious code. You can get the exploit from one of the many downloadable PoCs available on GitHub.
Let’s say you want to use cowroot.c
. Once it has downloaded you need to compile the code. The command for that is given in the source code:
gcc cowroot.c -o cowroot -pthread
After the exploit has compiled, all that is left is to run the exploit and you’re done! You now have a root shell. It really is as easy as that.
As this is a kernel exploit, the system will surely become unstable. By turning off periodic writeback as the root user you can make the system a little more stable so you could mess around a little longer. To do this use:
echo 0 > /proc/sys/vm/dirty_writeback_centisecs
Mitigation
The safest way to mitigate this vulnerability is to upgrade the kernel to a newer version which isn’t affected anymore.
Here is a list of the earliest kernel versions fixed in common Linux distributions:
- 3.2.0-113.155 - Ubuntu 12.04 LTS
- 3.13.0-100.147 - Ubuntu 14.04 LTS (Linux Mint 17.1)
- 3.16.36-1+deb8u2 - Debian 8https://www.cs.toronto.edu/~arnold/427/18s/427_18S/indepth/dirty-cow/index.html
- 4.4.0-45.66 - Ubuntu 16.04 LTS
- 4.8.0-26.28 - Ubuntu 16.10
- 3.10.0-327.36.3 - RHEL 7, CentOS 7
- 2.6.32-642.6.2 - RHEL 6, CentOS 6
- 2.6.18-416 - RHEL 5, CentOS 5
To check the version of your kernel you can use:
uname -a
Updating the kernel
If you discover that you are using an older version of the kernel which is still vulnerable, then here is a tutorial on how to update the kernel in Debian distributions, using apt
.
To update the kernel, you can use:
sudo apt-get dist-upgrade
After that you need to reboot the system:
sudo reboot
Conclusion
As you can see, it is very simple to exploit Dirty COW with the many proof-of-concepts available on the internet. Keeping your kernel up-to-date is important because you don’t know when the next exploit could be discovered.
- “A Guide to Kernel Exploitation: Attacking the Core” by Enrico Perla B.Sc. Computer Science University of Torino M.Sc. Computer Science Trinity College Dublin (Author), Massimiliano Oldani (Author)