文章总结: 本文实测DirtyFrag漏洞在Kubernetes环境中的影响,发现EKS和GKE集群在seccomp未设置或设为Unconfined时,攻击者可利用该Linux本地提权漏洞获得容器内root权限。关键防护措施包括启用RuntimeDefaultseccomp或应用Pod安全标准Restricted策略,前者通过阻断unshare调用有效防御,后者在GKE上可完全阻断攻击链。不同云环境存在差异,如Talos节点默认禁用用户命名空间。 综合评分: 85 文章分类: 漏洞分析,云安全,容器安全,安全建设,解决方案
Dirty Frag在Kubernetes中的实测
Dubito Dubito
云原生安全指北
2026年5月9日 08:35 江苏
在小说阅读器读本章
去阅读
注:本文翻译自 Juliet 的文章《Dirty Frag in Kubernetes: EKS and GKE Exposed With Unset Seccomp》[1],可点击文末“阅读原文”按钮查看英文原文。
全文如下:
一、引言
Dirty Frag 是 Hyunwoo Kim 在V4bel/dirtyfrag[2]中公开并作为 PoC 发布的一种 Linux 本地提权技术 。上游文章描述了两条页缓存(page-cache)写入路径:一条是 xfrm-ESP 路径,另一条是 RxRPC 路径。xfrm 路径需要创建用户命名空间(user namespace)和网络命名空间(network namespace)。RxRPC 路径本来适用于无法使用命名空间路径的环境,但它的前提是 RxRPC 可用。
上游文章主要关注 Linux。针对 Kubernetes,我们关心的问题更具体:
在一个普通 Pod 中,Dirty Frag 攻击链的哪些部分是可以触达的?Kubernetes 或节点的哪些控制措施可以真正阻断它?
我们在真实的 Kubernetes 集群和本地 kind 集群上做了测试。不同云提供商的差异确实有影响:
- • 在 Amazon Linux 2023 上的 EKS:在我们的实验环境中,当 seccomp 未设置或被设为
Unconfined时,可以被利用。 - • 在 Container-Optimized OS 上的 GKE:在我们的实验环境中,当 seccomp 未设置或被设为
Unconfined时,可以被利用。 - • 在我们本地实验室集群的 Talos 上:即使显式设置 seccomp 为
Unconfined,所测试的 xfrm 链也会被阻断,因为在节点层面用户命名空间(user namespace)被禁用了。 - •
RuntimeDefaultseccomp 通过拒绝unshare(USER|NET)的方式,在 EKS、GKE、Talos 以及本地 kind 上都阻断了所测试的 xfrm 链。 - • Pod 安全标准(Pod Security Standards)中的 Restricted 策略在 GKE 上阻断了完整的所测试的 xfrm PoC,在 EKS 和 Talos 上则阻断了所测试的 xfrm 前置条件。
本文的范围是刻意的。我们在 EKS 和 GKE 上证明了可以在受控的 Pod 中获得容器内的 root 权限。但我们没有证明能够获得宿主机的 root 权限,也没有证明能够实现容器逃逸。我们没有测试所有托管 Kubernetes 发行版、所有节点镜像、所有内核构建版本,也没有端到端地测试 RxRPC 备用路径。在我们测试的所有 Kubernetes 环境中,AF_RXRPC 都不被支持。
截至 2026 年 5 月 8 日,上游 Dirty Frag 的 README 仍然写着:禁运(embargo)已被打破,没有对应的 CVE 或补丁。请将此视为一个带时间戳的上游状态说明,不能替代厂商的安全公告。
二、主要发现
- • 在 EKS 和 GKE 上,seccomp 未设置的 Pod 会以
Seccomp: 0运行。xfrm Dirty Frag 路径可以成功,并拿到容器内的uid=0(root)。 - • 在 EKS 和 GKE 上,显式设置
seccompProfile.type: Unconfined也同样可以成功,并拿到容器内的uid=0(root)。 - • 在 EKS 和 GKE 上,
RuntimeDefaultseccomp 在页缓存标记发生变化之前,于unshare(USER|NET)这一步就阻断了该 PoC。 - • 在 GKE 上,PSS Restricted 策略通过
NoNewPrivs: 1、Seccomp: 2、移除能力(dropped capabilities)、拒绝unshare以及不变的/usr/bin/su的标记字节(unchanged/usr/bin/sumarker bytes)等方式,阻断了完整的PoC。在 EKS 和 Talos 上,PSS Restricted 则在同样的unshare(USER|NET)步骤阻断了所测试的 xfrm 前置条件。 - • 在 Talos 上,
user.max_user_namespaces=0即使 seccomp 显式设置为Unconfined,也会阻断 xfrm 路径。 - • 在我们测试的 kind、EKS、GKE 和 Talos 环境中,
AF_RXRPC均不可用,因此我们不声称对 RxRPC 备用路径进行了覆盖测试。 - • GKE 和 Talos 在我们测试的 Pod 中没有可用的
pcbc(fcrypt)。但在 GKE 上,当 seccomp 未设置或设为Unconfined时,xfrm 路径仍然成功。因此缺少pcbc(fcrypt)并没有让该 GKE 节点免于被 xfrm 链攻击。 - • 我们观察到 Kubernetes 可移植性方面的一个重要差异:在 EKS 和 GKE 上,不设置 seccomp 意味着
Seccomp: 0;而在 Talos 上,一个 seccomp 未设置的 Pod 在我们的测试中仍显示为Seccomp: 2。
三、Dirty Frag 是什么
上游的 Dirty Frag 项目描述了一类本地提权漏洞,它是基于页缓存写入原语构建的。其 README 显示,xfrm-ESP 页缓存写入路径自 2017 年 1 月的一个 Linux 提交起就已存在,而 RxRPC 路径自 2023 年 6 月的一个提交起就已存在。作者将 Dirty Frag 定位为与 Dirty Pipe 和 Copy Fail 相关,因为攻击者修改的是文件 backed 的页缓存内容,而不是常规磁盘上的文件字节。
公共 PoC 中的 xfrm 路径使用了用户命名空间和网络命名空间,通过 NETLINK_XFRM 配置 xfrm 状态,并对 /usr/bin/su 的缓存字节进行修补。在我们成功复现的 EKS 和 GKE 实验室环境中,Pod 以 uid 1000 启动,修改了 /usr/bin/su 的缓存字节,然后执行被修改后的路径,最终在容器内拿到 uid 0。
最后一句话需要明确边界:拿到容器内的 uid 0 并不等同于拿到宿主机的 root 权限。Kubernetes Pod 共享节点内核,但容器进程仍然运行在容器命名空间、挂载点以及剩余运行时隔离措施之内。
四、为什么 Kubernetes 改变了问题的性质
Kubernetes 团队不仅需要问“Linux 内核是否受影响”,他们还需要问:
- • 一个 Pod 能否创建用户命名空间和网络命名空间?
- • seccomp 是否真的被应用了?
- • seccomp 是未设置、
RuntimeDefault、Localhost,还是Unconfined? - • 节点是否允许非特权用户命名空间(unprivileged user namespaces)?
- • 内核是否暴露了
NETLINK_XFRM、AF_ALG和AF_RXRPC? - • PSS Restricted 策略是否应用到了该命名空间?
- • 不受信任的工作负载是否与敏感 Pod 被调度到了同一个节点上?
Kubernetes 将 seccomp 定义为一种限制从用户空间进入内核的系统调用的方式。Kubernetes 也支持 RuntimeDefault 配置文件和节点本地的 Localhost 配置文件。但 RuntimeDefault 并不是一个通用的单一配置文件。它是运行时所提供的默认配置文件,依赖于节点环境。
Pod 安全标准中的 Restricted 策略也不是万能的漏洞防护盾。它是一个基线。它要求启用一些在此场景下很重要的控制措施,包括禁止特权提升、启用 seccomp、以及移除所有能力(capabilities)。Kubernetes 规定,Restricted 容器必须删除 ALL 能力,并且只能重新添加 NET_BIND_SERVICE。在我们对 GKE 进行受限完整PoC的测试中,结果产生了 CapBnd: 0000000000000000、NoNewPrivs: 1 和 Seccomp: 2。
对于 Dirty Frag 的 xfrm 路径而言,在我们的测试中这些控制措施已经足够了。这与我们之前对 Copy Fail 的测试结果不同。在 Copy Fail 中,PSS Restricted 和 RuntimeDefault 并没有阻断 AF_ALG 的可达性。Dirty Frag 和 Copy Fail 都涉及页缓存相关领域,但它们在 Kubernetes 中的控制点并不相同。
五、我们测试了什么
我们使用了上游 commit 中的公开 Dirty Frag PoC 代码:
892d9a31d391b7f0fccb333855f6289507186748
在撰写本文之前,我们已将该 commit 与上游 master 分支进行了比对。
我们为 Kubernetes 测试构建了两个 amd64 二进制文件:
- • 一个探针(probe)二进制文件,用于记录内核/运行时信息,并测试
AF_RXRPC、NETLINK_XFRM、AF_ALG、pcbc(fcrypt)、keyring 调用、unshare(USER|NET)、uid/gid 映射写入、环回接口(loopback)设置,以及执行unshare之后的NETLINK_XFRM的可达性。 - • 一个基于公开
exp.c的PoC二进制文件,强制走 xfrm/ESP 路径,并在执行前后输出/usr/bin/su标记字节的日志。
每一次执行修改操作的运行(mutating run),我们都使用了一个特权的清理 Pod,在漏洞利用尝试之前和最终结束后分别清理页缓存。我们尽可能选择低密度的节点,使用了以 jdfrag-* 命名的短期命名空间,并在事后验证了这些命名空间已被删除。
成功的主要标志不仅仅是“进程退出码为零”。我们将以下所有条件同时满足才认定为可被利用:
- • 初始的 Pod uid 为非 root;
- • seccomp 状态与当前测试的用例相符;
- •
/usr/bin/su中的标记字节从0300000004000000变为了31ff31f631c0b06a; - • PoC 程序打印了 xfrm 页缓存修补消息;
- • shell 拿到了
uid=0(root); - • 执行了最终的清理操作。
六、EKS 结果:当 seccomp 未设置或为 Unconfined 时可被利用
EKS 的测试使用了一个非生产集群。目标节点是一个低密度的 Amazon Linux 2023 工作节点,在资产盘点时上面运行着 7 个 Pod。
Kubernetes: v1.34.7-eks-40737a8
OS image: Amazon Linux 2023.11.20260413
Kernel: 6.12.79-101.147.amzn2023.x86_64
Container runtime: containerd 2.2.1
6.1 EKS RuntimeDefault
RuntimeDefault 在命名空间创建阶段就阻断了 xfrm 链:
NoNewPrivs: 0
Seccomp: 2
Seccomp_filters: 1
DIRTYFRAG_EXP_BEFORE_MARKER 0300000004000000
[su] unshare: Operation not permitted
dirtyfrag: failed (rc=1)
DIRTYFRAG_EXP_AFTER_MARKER 0300000004000000
探针显示,在执行 unshare 之前 NETLINK_XFRM 和 AF_ALG 都是可达的,并且该 EKS 节点上存在 pcbc(fcrypt),但是 unshare(USER|NET) 被拒绝。对于 xfrm 链而言,这个拒绝是决定性的。
6.2 EKS seccomp 未设置
在未设置 seccomp 配置文件的情况下,Pod 以 Seccomp: 0 运行。探针显示 unshare(USER|NET) 成功,uid/gid 映射可以被写入,环回接口可以被启动,并且 unshare 之后 NETLINK_XFRM 也能正常工作。
完整的PoC成功拿到了容器内的 root 权限:
DIRTYFRAG_IDS_BEFORE uid=1000 gid=1000 groups=1000
CapEff: 0000000000000000
NoNewPrivs: 0
Seccomp: 0
Seccomp_filters: 0
DIRTYFRAG_EXP_BEFORE_MARKER 0300000004000000
[su] installed 48 xfrm SAs
[su] wrote 192 bytes to /usr/bin/su starting at 0x0
[su] /usr/bin/su page-cache patched (entry 0x78 = shellcode)
# uid=0(root) gid=0(root) groups=0(root)
root
DIRTYFRAG_EXP_AFTER_MARKER 31ff31f631c0b06a
6.3 EKS Unconfined
显式设置 seccompProfile.type: Unconfined 同样拿到了容器内的 root 权限,标记字节的变化和 uid=0(root) 的结果与之前一致。
6.4 EKS PSS Restricted
在 EKS 的受限(Restricted)探针中,结果为 NoNewPrivs: 1、Seccomp: 2、无有效能力(effective capabilities),并且 unshare(USER|NET) 被拒绝。在 GKE 的受限完整 PoC 确认了同样的失败点之后,我们没有在 EKS 的受限命名空间中运行完整的修改操作 PoC。我们经过验证的 EKS 结论范围更窄:PSS Restricted 阻断了我们测试的 xfrm 路径所需的前置条件。
七、GKE 结果:当 seccomp 未设置或为 Unconfined 时可被利用
GKE 的测试使用了一个开发/预发集群。目标节点是资产盘点时密度最低的 Container-Optimized OS 工作节点。
Kubernetes: v1.33.9-gke.1060000
OS image: Container-Optimized OS from Google
Kernel: 6.6.122+
Container runtime: containerd 2.0.7
7.1 GKE RuntimeDefault
RuntimeDefault 在 unshare(USER|NET) 这一步阻断了 xfrm 链:
NoNewPrivs: 0
Seccomp: 2
Seccomp_filters: 1
DIRTYFRAG_EXP_BEFORE_MARKER 0300000004000000
[su] unshare: Operation not permitted
dirtyfrag: failed (rc=1)
DIRTYFRAG_EXP_AFTER_MARKER 0300000004000000
7.2 GKE seccomp 未设置
在 GKE 上未设置 seccomp 的行为与 EKS 类似:Pod 以 Seccomp: 0 运行,用户命名空间和网络命名空间的创建成功,并且 unshare 之后 NETLINK_XFRM 也能正常工作。
完整的PoC成功拿到了容器内的 root 权限:
DIRTYFRAG_IDS_BEFORE uid=1000 gid=1000 groups=1000
CapEff: 0000000000000000
NoNewPrivs: 0
Seccomp: 0
Seccomp_filters: 0
DIRTYFRAG_EXP_BEFORE_MARKER 0300000004000000
[su] installed 48 xfrm SAs
[su] wrote 192 bytes to /usr/bin/su starting at 0x0
[su] /usr/bin/su page-cache patched (entry 0x78 = shellcode)
# uid=0(root) gid=0(root) groups=0(root)
root
DIRTYFRAG_EXP_AFTER_MARKER 31ff31f631c0b06a
7.3 GKE Unconfined
显式设置 Unconfined 同样拿到了容器内的 root 权限。其结果与 seccomp 未设置的情况一致:标记字节变为 31ff31f631c0b06a,PoC程序拿到了 uid=0(root)。
7.4 GKE PSS Restricted
我们在一个 PSS Restricted 命名空间中运行了完整的PoC。它在页缓存标记字节发生变化之前就失败了:
DIRTYFRAG_IDS_BEFORE uid=1000 gid=1000 groups=1000
CapEff: 0000000000000000
CapBnd: 0000000000000000
NoNewPrivs: 1
Seccomp: 2
Seccomp_filters: 1
DIRTYFRAG_EXP_BEFORE_MARKER 0300000004000000
[su] unshare: Operation not permitted
dirtyfrag: failed (rc=1)
DIRTYFRAG_EXP_AFTER_MARKER 0300000004000000
这是本次测试中最直接的防御结果:在 GKE 上,PSS Restricted 阻断了我们测试的完整 xfrm 链。
八、Talos 结果:被禁用用户命名空间阻断
本地实验集群同时包含 Talos 和非 Talos 节点。在最后一轮 Talos 测试中,我们选择了一个禁用了用户命名空间的 Talos 工作节点。
Kubernetes: v1.35.0
OS image: Talos v1.12.2
Kernel: 6.18.5-talos
Container runtime: containerd 2.1.6
在 Talos 的测试中,RuntimeDefault 和 seccomp 未设置的情况均显示 Seccomp: 2,并且 unshare(USER|NET) 被拒绝(返回 EPERM)。
更有趣的情况是显式设置 Unconfined:
DIRTYFRAG_PROBE status Seccomp: 0
DIRTYFRAG_PROBE proc max_user_namespaces 0
DIRTYFRAG_PROBE socket(NETLINK_XFRM) OK
DIRTYFRAG_PROBE socket(AF_ALG) OK
DIRTYFRAG_PROBE unshare(USER|NET) ERR errno=28 (No space left on device)
在显式 Unconfined 下,完整的PoC以同样的方式失败:
NoNewPrivs: 0
Seccomp: 0
DIRTYFRAG_EXP_BEFORE_MARKER 0300000004000000
[su] unshare: No space left on device
dirtyfrag: failed (rc=1)
DIRTYFRAG_EXP_AFTER_MARKER 0300000004000000
user.max_user_namespaces=0 足以阻断该 Talos 节点上的 xfrm 测试路径。这并不意味着“Talos 对 Dirty Frag 免疫”。它只是说明,在我们特定的 Talos 配置下,这个 Dirty Frag 的 xfrm 链无法通过命名空间设置的步骤。
九、本地 kind 测试结果
我们还在一个 arm64 架构的 OrbStack 主机上运行了本地 kind 集群。这对于控制测试很有用,但不是我们关于云提供商结论的核心依据。
在一个权限宽松的本地 kind 环境中,xfrm 路径确实修改了 /usr/bin/su 的标记字节。但由于我们使用的上游攻击载荷(payload)是 x86_64 架构,而宿主机是 arm64 架构,因此没有干净地切换到 root 权限。在 RuntimeDefault 和 PSS Restricted 的情况下,攻击链在 unshare(USER|NET) 处失败。
我们不把 kind 的结果作为云提供商存在风险证据。它只是一个可复现性的测试工具,以及一个防止将 Kubernetes YAML 行为与提供商行为混淆的校验手段。
十、为什么未设置 seccomp 是 Kubernetes 的 footgun(搬起石头砸自己的脚的设定)
在实际运维中,关键发现是在 EKS 或 GKE 上,不设置 seccomp 并不等同于 RuntimeDefault。
在这两个云提供商上:
- • 未设置 seccomp:
Seccomp: 0,xfrm 链成功,拿到容器 root 权限; - •
RuntimeDefault:Seccomp: 2,unshare(USER|NET)被拒绝,标记字节未变化; - •
Unconfined:Seccomp: 0,xfrm 链成功,拿到容器 root 权限。
团队通常会检查 Unconfined,但却容易忽略 seccomp 未设置的情况。对于 Dirty Frag 的 xfrm 路径而言,在我们 EKS 和 GKE 的实验环境中,这个区别决定了攻击是被阻断还是可以被利用。
十一、能够改变实验效果的控制措施
11.1 强制启用 seccomp,不要留空
对于我们测试的 xfrm 链,RuntimeDefault 在 EKS、GKE、Talos 和 kind 上都足以阻断 unshare(USER|NET)。
但这并不意味着 RuntimeDefault 是 Dirty Frag 的通用解决方案。它只说明:我们测试的这些运行时默认配置文件,阻断了我们测试的这条 xfrm 路径。如果某个不同的运行时默认配置允许创建用户命名空间和网络命名空间,结果可能会不同。
对于高风险工作负载,建议使用经过验证的 Localhost seccomp 配置文件,并在每个节点系列上进行测试。Kubernetes 支持将节点本地的 seccomp 配置文件应用到 Pod,但该配置文件必须存在于节点上,并且工作负载需要正确引用它。
11.2 对不受信任的工作负载强制使用 PSS Restricted
PSS Restricted 在 GKE 上阻断了我们所测试的完整 xfrm 链,并在 EKS 和 Talos 上阻断了所测试的前置条件。
相关的控制措施包括:
- •
allowPrivilegeEscalation: false,它会设置no_new_privs; - •
seccompProfile.type: RuntimeDefault或一个限制性的Localhost配置文件; - •
capabilities.drop: ["ALL"]; - • 以非 root 身份执行。
PSS Restricted 不能替代内核的漏洞修补,但它改变了这次PoC的结果。
11.3 考虑节点层面的用户命名空间限制
Talos 即使在显式设置 Unconfined seccomp 的情况下也能阻断 xfrm 路径,原因是 user.max_user_namespaces=0。
这对于这条攻击链来说是一个很强的控制措施,但它可能会破坏那些确实需要非特权用户命名空间的工作负载。请将其视为一个节点池层面的决策,而不是随意在整个集群范围内开关。构建运行器(build runner)、镜像构建工具、沙箱工具以及某些开发工作负载可能依赖用户命名空间。
11.4 将未设置或为 Unconfined 的 seccomp 视为高优先级的态势问题
对于 Dirty Frag 而言,在 EKS 或 GKE 上,一个 seccomp 未设置的 Pod 不仅仅是“加固程度较低”。在我们的实验环境中,它是可以被利用的。
请盘点所有运行中的 Pod,并标记出以下情况:
- • Pod 或容器级别未设置 seccomp;
- •
seccompProfile.type: Unconfined; - • 没有 PSS 标签的命名空间;
- •
allowPrivilegeEscalation: true或未设置; - • 没有移除所有能力(capabilities)的容器;
- • 运行在允许非特权用户命名空间的节点池上的工作负载。
11.5 跟随厂商安全公告,修补并替换节点
Dirty Frag 是一个 Linux 内核问题。Kubernetes 的策略可以降低被利用的可能性,但根本的修复还是在节点操作系统/内核层面。
请以厂商的安全公告和软件包状态为准。仅看内核版本号字符串可能会有误导性,因为厂商在向后移植修复补丁时,并不会把内核版本号改成与上游相同的版本号。
十二、Juliet 在此能做什么
这正是图视图(graph view)发挥作用的地方:答案分布在节点资产清单、工作负载态势和运行时信息之中。
针对 Dirty Frag 的暴露风险,有用的图包括:
- • 节点内核、操作系统镜像、Kubernetes 版本和容器运行时;
- • 工作负载与节点的对应关系;
- • 经过 Pod 级别和容器级别继承后的有效 seccomp 状态;
- • 命名空间上的 PSS 标签;
- •
allowPrivilegeEscalation、能力(capabilities)、特权模式、宿主命名空间(host namespaces)和hostPath; - • 节点信息,例如
user.max_user_namespaces,以及测试过的地址族(address families)是否可达。
Juliet 可以将这些信息转化为防御方需要回答的问题:
- • 哪些工作负载在 EKS 或 GKE 上正以未设置或
Unconfined的 seccomp 运行? - • 哪些命名空间没有强制启用 PSS Restricted?
- • 哪些高风险工作负载与敏感工作负载共享同一个节点?
- • 哪些节点系列需要针对 Dirty Frag 做一次针对性的验证测试?
- • 存在哪些补偿性控制措施?哪些措施并未降低风险?
Juliet 还可以帮助阻断我们已验证过的风险路径:
- • 准入策略(admission policy)可以拒绝那些 seccomp 未设置(unset)、使用
Unconfined、允许特权提升或未移除所有能力的新工作负载。 - • 可以逐个命名空间地推行 Kubernetes PSS Restricted 强制策略,同时 Juliet 会监控命名空间标签和工作负载态势,这样团队就能在从审计模式切换到强制模式之前,看到哪些工作负载会出问题。
- • 运行时策略可以检测到命名空间操纵行为,例如
unshare和setns;在强制模式下,Juliet 可以在命名空间范围内杀死匹配的容器进程,并配合限流防护措施。
这并不等于说 Juliet 能修补内核。最安全的控制栈依然是:修补或替换受影响的节点、对不受信任的工作负载强制使用 seccomp/PSS、并使用运行时强制作为漏洞利用行为的额外告警线。
想在自己的集群中检查这个问题吗?免费开始使用 Juliet[3],先接入一个非生产集群,然后使用 Explorer 检查 seccomp 状态、命名空间 PSS 标签、工作负载分布和节点信息。如果你希望我们和你一起进行检测,请申请 Dirty Frag 暴露风险评估[4]。
十三、我们未证明的内容
请不要过度解读本文。
我们并未证明每一个 EKS 集群都可被利用。我们只测试了一个 EKS 集群、一个 Amazon Linux 2023 节点系列、一个内核构建版本和一个 containerd 构建版本。
我们并未证明每一个 GKE 集群都可被利用。我们只测试了一个 GKE 集群、一个 COS 节点系列、一个内核构建版本和一个 containerd 构建版本。
我们并未证明 Talos 能够普遍地阻断 Dirty Frag。我们只证明:在我们的 Talos 节点上,由于设置了 user.max_user_namespaces=0,它阻断了所测试的 xfrm 路径。
我们并未证明能够获取宿主机 root 权限、实现节点持久化或完成容器逃逸。
我们没有端到端地测试 RxRPC 备用路径,因为在我们测试的所有环境中,AF_RXRPC 都不被支持。
本文中我们不会公开漏洞利用代码、实验补丁或复现命令。
十四、防御方检查清单
即时检查项:
- • 找出有效 seccomp 为未设置(unset)或
Unconfined的 Pod。 - • 对不受信任的工作负载强制使用
RuntimeDefault或经过验证的Localhostseccomp 配置文件。 - • 在运行不受信任或多租户工作负载的命名空间上,强制启用 PSS Restricted。
- • 确认设置了
allowPrivilegeEscalation: false和capabilities.drop: ["ALL"]。 - • 检查每个节点池上的节点级别用户命名空间策略。
- • 将构建任务、CI 作业、插件执行和用户控制的代码与敏感工作负载隔离开。
- • 跟进厂商的内核安全指引,规划节点替换或补丁部署。
验证性检查项:
- • 不要假设 YAML 的意图就等于运行时行为。应在测试 Pod 内部查看
/proc/self/status,确认Seccomp的实际值。 - • 分别测试有代表性的节点池。EKS、GKE、Talos 和 kind 的表现并不相同。
- • 在任何经过授权的验证性测试之后,确认清理工作已完成且节点健康状况正常。
- • 单独对待
AF_RXRPC。由于我们环境中不支持该协议,我们无法测试那条备用路径。
十五、常见问题解答
15.1 Dirty Frag 是 Kubernetes 的漏洞吗?
不是。这是一个 Linux 内核问题。Kubernetes 之所以重要,是因为 Pod 共享节点的内核,而 Kubernetes 的策略决定了 Pod 是否能够触达漏洞利用链所需的内核原语。
15.2 RuntimeDefault 能阻止 Dirty Frag 吗?
在我们 EKS、GKE、Talos 和 kind 的实验中,RuntimeDefault 通过拒绝 unshare(USER|NET),阻断了我们测试的 xfrm 路径。请不要未经测试就将其推广到每一个运行时或每一个未来的 Dirty Frag 变种。
15.3 PSS Restricted 能阻止 Dirty Frag 吗?
在我们实验中,PSS Restricted 阻断了我们测试的 xfrm 链。在 GKE 上,我们在 PSS Restricted 下运行了完整的PoC,它在标记字节(marker bytes)变化之前就失败了。在 EKS 和 Talos 上,Restricted 阻断了我们测试的前置条件,包括 unshare(USER|NET)。
15.4 EKS 和 GKE 可以被利用吗?
在我们实验室环境中,是的——当 seccomp 未设置或被显式设为 Unconfined 时。结果是拿到了 Pod 内部的容器 root 权限,而非已证明的宿主机 root 权限。
15.5 Talos 可以被利用吗?
在我们最终的 Talos xfrm 测试中,答案是否定的。显式设置 Unconfined seccomp 虽然产生了 Seccomp: 0,但 user.max_user_namespaces=0 导致 unshare(USER|NET) 以 ENOSPC 错误失败。
15.6 最重要的首要检查项是什么?
找出在允许用户命名空间的节点池上,那些 seccomp 未设置或为 Unconfined 的 Pod。在 EKS 和 GKE 的测试中,这是对可利用性最强的预测指标。
参考链接
- • V4bel/dirtyfrag 上游仓库[2]
- • Dirty Frag 上游技术文章[5]
- • Kubernetes Pod 安全标准[6]
- • Kubernetes seccomp 文档[7]
引用链接
[1] 《Dirty Frag in Kubernetes: EKS and GKE Exposed With Unset Seccomp》: https://juliet.sh/blog/we-tested-dirty-frag-in-kubernetes-eks-gke-talos-seccomp
[2] V4bel/dirtyfrag: https://github.com/V4bel/dirtyfrag
[3] 免费开始使用 Juliet: https://app.juliet.sh/register?plan=starter
[4] 申请 Dirty Frag 暴露风险评估: mailto:[email protected]?subject=Dirty%20Frag%20Kubernetes%20exposure%20review
[5] Dirty Frag 上游技术文章: https://github.com/V4bel/dirtyfrag/blob/master/assets/write-up.md
[6] Kubernetes Pod 安全标准: https://kubernetes.io/docs/concepts/security/pod-security-standards/
[7] Kubernetes seccomp 文档: https://kubernetes.io/docs/tutorials/security/seccomp/
交流群
知识库
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:云原生安全指北 Dubito Dubito《Dirty Frag在Kubernetes中的实测》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论