脏页漏洞:一个针对容器和微型虚拟机沙箱的内核零日漏洞
1 分•作者: ShivamNayak11•大约 1 个月前
5月7日,Hyunwoo Kim (V4bel) 披露了 Dirty Frag——两个 Linux 内核漏洞(CVE-2026-43284 和 CVE-2026-43500),这些漏洞允许非特权用户在自 2017 年以来发布的大多数 Linux 发行版上获得确定的 root 权限。微软在第二天确认了主动利用行为。<p>我们在 Firecracker 微型虚拟机上构建 declaw.ai——用于 AI 代理的沙盒基础设施。我们运行着我们不编写且无法预测的不可信代码,因此当 Dirty Frag 出现时,我们的第一个问题是:我们的隔离边界是否牢固?我们在一颗故意<i>未打补丁</i>的内核上进行了测试。它保持了隔离。原因如下。<p>该漏洞利用是一个页面缓存写入原语:它欺骗内核覆盖任何文件(/usr/bin/su, /etc/passwd)的内存内容,并提供 root 权限。完全确定,没有竞争条件。<p>为什么这对于多租户平台很重要:页面缓存由整个机器共享。容器共享宿主内核,命名空间隔离、seccomp 和已删除的权限都是由该内核强制执行的。内核漏洞利用不需要逃逸容器——它在容器隔离存在的层之下运行。与 Dirty COW (2016) 和 Dirty Pipe (2022) 存在相同的结构性问题。在零日漏洞出现当天,在任何补丁存在之前,每个共享该内核的基于容器的沙盒都会暴露。打补丁是在事后关闭窗口;它无法提前关闭。<p>我们在两种环境中运行了公开的 PoC(ESP 路径,CVE-2026-43284)。<p>测试 1——容器沙盒(Docker,seccomp 开启,非特权 uid=1001,宿主内核 6.8.0):非特权用户在 2 秒内获得 root 权限。Seccomp 处于活动状态,但没有帮助——所需的系统调用被配置文件允许。拥有 root 权限后,我们读取了 /etc/shadow、宿主内核启动参数和 Docker overlay2 路径。<p>测试 2——Firecracker 微型虚拟机(未打补丁的客户内核,无 seccomp,以 root 身份启动,具有完全权限——有意比测试 1 更宽松)。该漏洞利用在客户机<i>内部</i>有效,但每次尝试访问宿主机的尝试都失败了:宿主内核不可见,宿主机进程不可见(客户机有自己的 kthreadd/kswapd),所有宿主机端口都关闭,只有虚拟块设备,没有宿主机硬件身份。它损坏的页面缓存属于客户机自己的内核,通过 EPT 映射到宿主内存的受限区域。<p>不对称性是关键:微型虚拟机以比容器更高的权限启动,但仍然无法访问宿主机。重要的是软件授予的权限,而不是内核是否被共享。要逃逸 Firecracker,您需要在 VMM(约 5 万行 Rust 代码)或 KVM 中找到一个漏洞;谷歌的 kvmCTF 为客户机到宿主机的逃逸支付 25 万美元,并且只有一次被公开演示。<p>如果您运行多租户的不可信代码,任何隔离提供商的问题是:如果沙盒内的代码获得 root 权限,它是否可以访问宿主机或其他租户?如果答案是“只要我们打了补丁”——这就是差距。<p>PoC:https://github.com/V4bel/dirtyfrag
完整说明(命令 + 输出):https://declaw.ai/blog/dirty-frag-microvm-isolation
查看原文
On May 7, Hyunwoo Kim (V4bel) disclosed Dirty Frag — two Linux kernel
vulnerabilities (CVE-2026-43284 and CVE-2026-43500) that give unprivileged
users deterministic root on most Linux distributions shipped since 2017.
Microsoft confirmed active exploitation the next day.<p>We build declaw.ai — sandboxing infrastructure for AI agents, on Firecracker
microVMs. We run untrusted code we don't write and can't predict, so when
Dirty Frag dropped our first question was: does our isolation boundary hold?
We tested it on a deliberately <i>unpatched</i> kernel. It held. Here's why.<p>The exploit is a page-cache write primitive: it tricks the kernel into
overwriting the in-memory contents of any file (/usr/bin/su, /etc/passwd) and
gives root. Fully deterministic, no race.<p>Why it matters for multi-tenant platforms: the page cache is shared across
the whole machine. Containers share the host kernel, and namespace isolation,
seccomp, and dropped capabilities are all enforced <i>by</i> that kernel. A kernel
exploit doesn't need to escape the container — it operates below the layer
where container isolation exists. Same structural issue as Dirty COW (2016)
and Dirty Pipe (2022). On the day a zero-day drops, before any patch exists,
every container-based sandbox sharing that kernel is exposed. Patching closes
the window after the fact; it can't close it in advance.<p>We ran the public PoC (ESP path, CVE-2026-43284) in two environments.<p>Test 1 — container sandbox (Docker, seccomp on, unprivileged uid=1001, host
kernel 6.8.0): unprivileged user to root in under 2 seconds. Seccomp was
active but didn't help — the required syscalls were permitted by the profile.
With root we read /etc/shadow, host kernel boot params, and Docker overlay2
paths.<p>Test 2 — Firecracker microVM (unpatched guest kernel, no seccomp, started as
root with full capabilities — intentionally MORE permissive than test 1). The
exploit worked <i>inside</i> the guest, but every attempt to reach the host
failed: host kernel not visible, host processes invisible (the guest has its
own kthreadd/kswapd), all host ports closed, only virtual block devices, no
host hardware identity. The page cache it corrupted belongs to the guest's
own kernel, mapped to a bounded region of host memory via EPT.<p>The asymmetry is the point: the microVM started with more privilege than the
container and still couldn't reach the host. What matters isn't what
permissions the software grants — it's whether the kernel is shared. To
escape Firecracker you'd need a bug in the VMM (~50K lines of Rust) or KVM;
Google's kvmCTF pays $250K for a guest-to-host escape and only one has ever
been publicly demonstrated.<p>If you run untrusted code multi-tenant, the question for any isolation
provider: if code inside the sandbox becomes root, can it reach the host or
other tenants? If the answer is "as long as we're patched" — that's the gap.<p>PoC: https://github.com/V4bel/dirtyfrag
Full writeup (commands + output): https://declaw.ai/blog/dirty-frag-microvm-isolation