虚拟化安全入门:如何看懂QEMU CXL逃逸PoC的Guest到Host完整路径
【免费下载链接】exploitariumA single archive of public exploit PoCs and vulnerability research writeups. At the time I post these, none have been reported. Feel free to report them yourself and take credit for the CVE if handed out lulz. Please do not abuse these. I do this so to allure people into the field, and I've always found this is the most efficient way.项目地址: https://gitcode.com/GitHub_Trending/ex/exploitarium
在虚拟化安全领域,QEMU CXL 逃逸一直是新手难以入门的高阶话题。本文带你从 Guest(客户机)视角出发,完整拆解 Exploitarium 仓库中的 qemu-cxl-type3-mailbox-escape-poc —— 一个利用 QEMU 内置 CXL 邮箱处理缺陷,最终在宿主机进程中执行命令的完整 PoC。
仓库说明:Exploitarium 是一个公开漏洞 PoC 与漏洞研究写作的归档合集。作者声明发布时均未上报,请勿恶意使用,仅供学习研究。
一、为什么这个 PoC 值得学? 🎯
虚拟化安全的核心问题只有一个:能不能从虚拟机里"逃"出来?
大多数新手接触虚拟化安全,只能看到虚拟机"跑着",却不懂宿主机模拟层是怎么被攻击的。这个 PoC 的价值在于:
- 目标真实:针对上游 QEMU(版本 11.0.50)的 CXL Type-3 设备实现;
- 链路完整:从信息泄漏 → 伪造对象 → 控制跳转 → 宿主机执行命令,一步不落;
- 自包含:一个软盘镜像 + 两个脚本,即可完成全流程回放。
它演示了虚拟化逃逸中最经典的思路:宿主机模拟代码会处理 Guest 的输入,只要输入校验有漏洞,Guest 就能"借"宿主机的代码执行自己的意图。
二、PoC 文件结构:每个文件干什么
整个 PoC 只有 6 个文件,非常清晰:
| 文件 | 作用 |
|---|---|
| poc.img | 预构建的 BIOS 软盘镜像,虚拟机从它启动 |
| boot.asm | 16 位引导加载器,把保护模式阶段读入内存 |
| stage2.c | 核心:32 位 Guest 阶段,驱动 PCI 与 CXL 邮箱 |
| stage2.ld | 平坦保护模式链接脚本 |
| run.sh | 启动带 CXL Type-3 的 QEMU 并检查宿主机标记文件 |
引导流程在 boot.asm 中完成:关闭中断 → 用 BIOS 中断int 0x13从软盘读入 stage2 → 设置 GDT 并打开分页 → 跳入 32 位保护模式入口。
三、Guest 到 Host 的逃逸链路 🔍
整个利用链可以概括为"四步走",源码全部在 stage2.c 中:
1️⃣ 配置 PCI,把 CXL 设备"摆"到固定地址
Guest 先通过 PCI 配置端口把 CXL 根端口和 Type-3 端点的 BAR 固定下来(COMP_BAR = 0xe0000000,邮箱寄存器位于DEV_REG_BAR + 0x88)。这样后续所有攻击操作都有了确定的"操作台"。
2️⃣ 用 GET_LOG 命令泄漏宿主机指针
CXL 邮箱的GET_LOG处理器存在边界检查缺陷:它把offset当作字节范围检查,却又把它当数组下标使用,导致越界读。PoC 利用这一点(见 leak_rel 函数),两次泄漏出关键信息:
- QEMU 文本段指针(handler 地址)→ 减去函数偏移即得 QEMU 的 PIE 基址;
- 宿主机
CXLType3Dev对象指针→ 后续伪造对象要"种"在它附近的堆内存里。
3️⃣ 用 SET_FEATURE 命令伪造 QEMU 内存 API 对象
SET_FEATURE的 rank-sparing 分支把 Guest 数据不做目的边界检查地memcpy进rank_sparing_wr_attrs + offset,于是 PoC 往 CXL Type-3 对象尾部连续写入了 7 个伪造结构:动态容量状态、FlatView、AddressSpaceDispatch、MemoryRegionSection、MemoryRegion、MemoryRegionOps,以及一条命令字符串(见 forge_payload 函数)。
其中最关键的是伪造的MemoryRegionOps.write回调——它的函数指针指向哪里,宿主机就执行哪里。
4️⃣ 用 MEDIA_OPERATIONS 触发伪造回调
发送 sanitize 命令后,QEMU 会对伪造的动态容量地址空间调用address_space_set(),随即命中伪造的 write 回调。PoC 分两轮触发:
- 第一轮:回调指向
memmove@plt,借此把 GOT 表中的__libc_start_main值"搬"出来,反推出libc 基址和system()地址; - 第二轮:回调直接指向
system(),参数就是标记命令(stage2.c#L66-L67):
id>/tmp/qemu_cxl_escape_marker至此,Guest 在 QEMU 宿主机进程内执行了任意命令,逃逸完成。
四、一键复现:回放步骤 ⚡
只需一个支持 CXL Type-3 的qemu-system-x86_64,在项目目录下运行(见 run.sh):
sh run.sh /absolute/path/to/qemu-system-x86_64脚本以 q35 +cxl=on机型启动 QEMU,挂上poc.img软盘,超时 60 秒后读取串口日志,并用test -f检查标记文件是否存在。成功时你会看到 Guest 串口打印出的泄漏链和宿主机身份:
stage2 start pci done handler=0x00005d41f6d636f0 qemu_base=0x00005d41f68b6000 ct3d=0x000077f609b3a010 ... fake system call media-op sent bg done stage2 done uid=1000(owner) gid=1000(owner) groups=1000(owner),.../tmp/qemu_cxl_escape_marker文件中的uid=输出,就是回调真正落入宿主机 libcsystem()的铁证。
如需从零重建镜像,构建依赖仅为nasm、支持 32 位 freestanding 的gcc、ld和python3,运行sh build.sh即可(镜像哈希与二进制哈希的对应关系见 README.md#L36-L46)。
五、从 Guest 到 Host:新手要记住的 3 个要点 📌
要点 1:边界检查要"统一口径"
GET_LOG 缺陷的根源是"用一种单位检查,用另一种单位使用"。审计模拟层代码时,凡是offset/length既做范围判断又做索引的位置,都要重点盯防。
要点 2:宿主机对象可被 Guest 数据污染
SET_FEATURE 的无边界memcpy让 Guest 得以在宿主机堆上"种"下伪造对象。这说明:宿主机里任何能被 Guest 输入影响的结构体,都可能成为伪造对象的目标。
要点 3:泄漏 + 伪造 + 触发 = 标准逃逸三段式
本 PoC 的三段式(泄漏基址 → 伪造函数指针 → 借宿主机流程触发)是虚拟化逃逸的通用模板,理解了它,再看其他 QEMU/KVM 逃逸 PoC 会容易得多。
六、给新手的安全建议 🛡️
- 保持 QEMU 及相关组件及时更新,本 PoC 针对的上游提交为
30e8a06b64aa(见 README.md#L22-L28); - 生产环境开启 KVM 硬件虚拟化并限制不必要的模拟设备(CXL 设备非常规设备,按需启用);
- 对承载多租户虚拟化的宿主机,做好进程隔离与最小权限配置,即使模拟层被突破也能限制爆炸半径。
⚠️ 声明:本仓库所有内容均为善意的公开披露研究,旨在吸引更多人进入安全领域。在任何情况下都不要恶意使用,也请勿将 PoC 用于未授权目标。Cybercrime is cringe.
想获取更多同类型的 PoC 研究?本仓库还收录了 Docker、OpenSSH、Ghidra、libssh2 等 30+ 项目的漏洞 PoC与写作用作学习素材,完整清单见 README.md#L25-L67。
【免费下载链接】exploitariumA single archive of public exploit PoCs and vulnerability research writeups. At the time I post these, none have been reported. Feel free to report them yourself and take credit for the CVE if handed out lulz. Please do not abuse these. I do this so to allure people into the field, and I've always found this is the most efficient way.项目地址: https://gitcode.com/GitHub_Trending/ex/exploitarium
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考