从 VNCTF2024 的一道题学习QEMU Escape

💡 原文中文,约15000字,阅读约需36分钟。
📝

内容提要

本文介绍了利用QEMU漏洞进行pwn的方法,通过修改pci设备的内存区域来劫持控制流并执行后门函数。文章提供了完整的EXP代码,并介绍了攻击的步骤。

🔎

延伸解读

从用户态到虚拟化:QEMU逃逸的思维转换

文章作者以用户态pwn的经验切入QEMU逃逸,发现QEMU本身也是一个运行在操作系统上的程序,其漏洞利用思路与用户态pwn相似:先泄露地址(如PIE基址和堆地址),再劫持控制流执行后门。但难点在于需要理解虚拟化层:QEMU模拟的PCI设备通过MMIO与Guest交互,而MMIO的读写函数(vn_mmio_read/write)存在越界读写漏洞,可操控QEMU堆上的MemoryRegion结构。这要求攻击者熟悉QEMU的对象模型(QOM)和内存布局,否则难以定位关键指针。

漏洞利用的关键:越界读写与MemoryRegion结构

文章详细分析了vn_mmio_write和vn_mmio_read的越界读写能力:通过向偏移0x10写入负数,可以上溢读取或写入堆内存。利用这一点,作者读取了QEMU堆上的数据,并识别出MemoryRegion结构中的ops指针(偏移-24处)。通过将ops指针覆盖为指向可控区域(如堆上的零填充区),并在该区域布置后门函数地址,最终在触发MMIO操作时劫持控制流。这一过程展示了如何将越界读写转化为代码执行,核心在于对MemoryRegion结构的精准定位和利用。

动态调试技巧:在Docker中调试QEMU

文章记录了在Docker容器内调试QEMU的步骤:首先修改Dockerfile安装qemu-system-x86和gdb,然后通过docker cp将静态编译的exp放入rootfs并重新打包,修改run.sh以启用调试。在容器内启动QEMU后,使用gdb attach到QEMU进程,即可进行动态分析。作者还展示了如何通过gdb的find命令在堆内存中搜索特定值(如ops指针),从而定位MemoryRegion结构。这些技巧对于CTF中调试虚拟化环境具有实用参考价值。

利用链构建与EXP编写要点

文章给出了完整的EXP代码,其核心步骤包括:通过mmap映射resource0文件以读写MMIO空间;利用越界读泄露PIE基址和堆地址;计算后门函数地址(pie+0x67429B)和system_plt地址;在堆上布置命令字符串(如"cat flag")和函数指针;最后通过mmio_write_idx写入伪造的ops指针,并触发MMIO操作执行后门。EXP中使用了mmio_write_idx辅助函数来简化越界写操作。需要注意的是,地址计算依赖于泄露的堆地址和固定偏移,因此调试时需确认偏移的正确性。

❓

Q&A

如何利用QEMU漏洞进行pwn攻击?

通过修改pci设备的内存区域来劫持控制流并执行后门函数。

EXP代码的作用是什么?

EXP代码用于实现控制流劫持,成功执行后门函数。

在攻击过程中如何进行静态分析?

通过分析Dockerfile和启动脚本,了解QEMU的启动过程和pci设备的内存映射。

动态调试QEMU的步骤是什么?

使用docker调试QEMU,修改启动脚本和Dockerfile,运行EXP进行调试。

如何通过mmio攻击实现控制流劫持?

通过修改resource0的内容,操控vn_mmio_read和vn_mmio_write函数来实现控制流劫持。

学习QEMU和虚拟化知识的重要性是什么?

深入理解QEMU和虚拟化知识有助于更好地进行安全研究和漏洞利用。

🏷️

标签

➡️

继续阅读