// RESEARCH_TRANSMISSION ID: HITCON_2026_PWN2OWNOTHING_
PUBLISHED
READ_TIME6 MIN
PAYLOAD2,874 CHAR
BEGIN_PAYLOAD20261013
…
前言
这个议题于2026年8月21日在 HITCON 2026 上分享,由 Bruce Chen、Peterpan0927、Weiming Shi、Jheng Bing Jhong Co-write,议题详情见官方议程[1]。
大致的议题介绍:
This year’s Pwn2Own Berlin introduced QEMU-KVM on RHEL as a target, with an additional prize awarded for achieving cross-tenant code execution during the competition. Motivated by this challenge, we began an in-depth security research of the QEMU-KVM virtualization stack, spending around one month on both vulnerability research and exploit development across the QEMU-KVM and RHEL environment.
During our research, we successfully developed a full-chain exploit capable of achieving cross-tenant code execution by compromising both QEMU-KVM and the underlying host system. Although we were ultimately unable to register our entry in time due to submission limitations and the high number of participants, we believe the journey and findings are still worth sharing with the community.
In this talk, we will present our research methodology, discuss the vulnerabilities used throughout the exploit chain, and explain how we bypassed modern mitigations including seccomp sandboxing, SELinux, and Intel CET. We will also share interesting stories and challenges encountered during the process, as well as how we turned individual vulnerabilities into a reliable cross-tenant attack in a real-world virtualization environment.
……
议题分析
Pwn2Own Berlin 2026 中 KVM 类目的奖金是 $50,000(5 个 Master of Pwn 积分),在此基础上完成 cross-tenant 代码执行还有 $50,000 的 Add-on Bonus。议题的攻击场景非常明确:宿主机是裸机 RHEL(qemu-kvm 版本 10.0.0-14.el10_1.5,RHEL 10.1,VM 由 Cockpit 拉起并默认开启沙箱),攻击者控制租户 A 的 Guest(已拿到 root),目标是三步走:
- VM escape,控制宿主机上的 qemu-kvm 进程(ring 3)
- LPE,进入宿主机内核(ring 0)
- 以宿主机的控制权攻击租户 B 的 VM,完成 cross-tenant 代码执行
整条链路一共用了 3 个漏洞,加上一连串针对缓解措施的绕过技巧。
漏洞链
- Bug 1 — virtio-gpu
calc_image_hostmem整数溢出(OOB write):hw/display/virtio-gpu.c中width可控且按 32 位有符号整数运算,取width = 0x10000001时width*bpp被截断,导致分配远小于实际需求的 buffer,最终拿到一个最大约 1 GiB 的越界写。有意思的是这其实是个 N-day(CVE-2026-3886,DEVCORE 上报),团队直到对比上游 QEMU 代码时才发现,但目标版本直到比赛当天都没修。- 利用方式也很巧妙:OOB write 的目标选的是动态链接器 ld-linux.so 里的全局数据
_rtld_local(buffer 与它的偏移每次启动固定),覆写_ns_loaded(link_map 链表头)挂上伪造的 link_map;关闭 Guest VM 触发进程退出时的_dl_fini(),遍历链表调用伪造的DT_FINI_ARRAY[0],此时 RDI 就是 fake link_map 本身 —— RIP 和第一个参数同时可控。
- 利用方式也很巧妙:OOB write 的目标选的是动态链接器 ld-linux.so 里的全局数据
- Bug 2 — Buffer OOB read(信息泄露):正式比赛环境用 VM manager 启动,SLIRP 被 ZDI 划出攻击范围(我一开始在 SLIRP 里找到的泄露洞 CVE-2026-9539 因而作废,赛后才上报)。于是换个思路:既然手里有 OOB write,就用它改掉某个”特定结构体”,之后 QEMU 会把其中一个成员当作长度,把 QEMU 进程内存拷贝进 GPA(Guest 物理地址),长度可控且无边界检查,Guest 直接从 GPA 读回泄露数据。(slide 中该漏洞组件被打码,细节等 QEMU 官方公开,见 qemu work_items/3863)
- Bug 3 — CVE-2026-23394:unix_gc 竞争条件(LPE):
__unix_gc在不持 iolock 的情况下 purge skb,而unix_stream_read_generic持锁 peek skb,两者之间存在竞争窗口;skb 被__skb_queue_purge释放后,另一侧consume_skb仍在使用,造成 UAF。用 skb_data 喷 order-0 页面占回被释放的 skb,伪造skb->destructor即可控制 RIP。
缓解措施与绕过
这部分是议题最硬核的内容,比赛环境里的三座大山:
- seccomp:Cockpit 拉起 qemu-kvm 时带
-sandbox on,...,spawn=deny,fork/execve全被禁,system()直接没戏;但open/read/write/lseek/ioctl/socket还留着。 - SELinux(sVirt):qemu-kvm 进程域为
svirt_t,配合 MCS level 做租户间隔离,且 W^X —— 不能 mmap/mprotect 出可执行内存、不能 memfd_create + mmap(RX)、不能写文件再执行,常规 shellcode 落地手法全灭。 - Intel CET:理论上 user space 有 SHSTK(挡 ROP)、kernel 有 IBT(挡 JOP/COP)。
公开 slide
这里公开 slide , 感兴趣的同学可以自行阅读
Reference link
EOFCHECKSUM_OK