From virtio-snd 0-Day to Hypervisor Escape: Exploiting QEMU with an Uncontrolled Heap Overflow
本文展示了如何将一个看似"无法利用"的堆溢出漏洞转变为可靠的QEMU客户机到主机逃逸,滥用了新的glibc分配器行为和QEMU特定的堆喷洒技术。
漏洞发现
研究人员在寻找可研究设备时,专注于过去关注较少的设备。从virtio-snd(虚拟声卡设备)开始,发现了三个漏洞:
- 整数下溢:virtio_snd_handle_rx_xfer中的大小计算发生下溢
- 不匹配的最大值计算:virtio_snd_pcm_in_cb中的max_size计算与分配逻辑不匹配,导致最多8字节的OOB写入
- 缺失的边界检查:传递给AUD_read的大小没有考虑实际缓冲区分配大小,导致任意长度的OOB写入(最高可达4096字节)
有趣的时间点:这些漏洞已经在QEMU中存在两年多,但在研究人员独立发现它们的同一周被修复。
利用挑战
这些漏洞都在音频输入路径中。由于音频数据来自主机端,从漏洞利用角度来看,写出的字节是有效随机的。
这是一个有趣的挑战:当你无法控制写入的数据时,如何利用越界写入?
利用技术
1. 寻找更好的原语
第一个想法是瞄准某种大小或偏移字段。但大多数情况下,字段前面有一个或多个指针,会导致无效解引用并崩溃。
2. glibc分配器攻击
研究人员转向glibc分配器。虽然分配器技术通常更具版本特定性,但可以提供更可靠的利用路径。
3. 利用方法
- 利用glibc分配器的chunk布局和bin结构
- 使用unsorted bin attack修改内存
- 通过tcache poisoning控制分配
- 最终实现代码执行并逃逸到主机
技术细节
漏洞存在于QEMU的virtio-snd设备实现中。当guest虚拟机发送请求时,请求由运行在QEMU进程中的代码解析和处理。设备实现中的任何未处理边缘情况都可能导致某种主机状态损坏。
通信机制:guest端的virtio驱动程序通过virtqueues共享请求,而主机端的virtio设备消费这些请求、处理并返回响应。