停止担忧’allowPrivilegeEscalation'
Kubernetes安全上下文允许您在Pod或容器级别配置安全选项。虽然某些参数已被充分理解,但其他参数可能更加晦涩和令人困惑。在本文中,我们将揭穿关于allowPrivilegeEscalation选项的迷思。
TL;DR - allowPrivilegeEscalation是一个安全加固选项,不多不少。如果您能够将其关闭作为快速胜利,请务必这样做!否则,它本身不会让您被黑客攻击。如果您没有显式禁用它,可能也没问题。
什么是’allowPrivilegeEscalation’?
询问任何安全工程师是否应该允许您的应用程序"提升权限",您可能会得到茫然的目光、困惑的表情,甚至可能有人质疑您的理智。
幸运的是,这里存在误解。当您问:“如果我不显式将’allowPrivilegeEscalation’标志设置为false,有关系吗?“时,您的安全工程师听到的是:“如果我不安全的Java应用程序可以逃逸其容器并在我们的集群中跳舞,就像1999年一样,可以吗?”
好消息!你们至少有一个共同点:你们都不知道allowPrivilegeEscalation标志的含义——老实说,谁能责怪你们呢?
关于’allowPrivilegeEscalation’的常见误解
让我们开门见山:虽然关闭allowPrivilegeEscalation可能有价值,但它是一个安全加固设置,您可以在容器化环境中利用它来提高安全性。
特别是,如果您将allowPrivilegeEscalation保留为true(其默认值):
- 它不会神奇地允许容器中的非特权进程将其权限提升到root
- 它不会允许在容器内运行的进程逃逸容器
- 它不会允许Pod在集群内执行任何类型的权限提升
‘allowPrivilegeEscalation’实战
让我们重现一个场景,其中漏洞允许非特权进程在容器内将其权限提升到root。这可能发生在内核级漏洞中,如DirtyCow、DirtyPipe或OverlayFS中的CVE-2023-0386。我们还可以测试一个更简单(但同样现实)的场景:滥用具有setuid位设置的root拥有的二进制文件。
我们将使用以下程序,该程序使用setreuid(如"设置真实和有效用户ID”)和setregid来有效地将权限提升到root。根据设计,这仅在二进制文件由root拥有并设置了setuid位时才有效:
|
|
编译和设置setuid位:
|
|
以下Dockerfile模拟了一个Alpine容器镜像,该镜像以非特权用户身份运行应用程序,其中包含易受攻击的二进制文件:
|
|
构建镜像并在Kubernetes集群中运行,显式打开allowPrivilegeEscalation(即使这是默认值):
|
|
正如预期的那样,我们能够利用漏洞将权限提升到root。
但是,如果我们将allowPrivilegeEscalation设置为false启动Pod,我们会得到不同的结果:对setreuid和setregid的调用失败。
‘allowPrivilegeEscalation’如何工作
根据Kubernetes文档:
AllowPrivilegeEscalation控制进程是否可以获得比其父进程更多的权限。此布尔值直接控制是否将在容器进程上设置no_new_privs标志。
no_new_privs标志是3.5内核中引入的内核功能(于2012年发布)。启用时,它确保没有子进程可以获得比其父进程更多的权限。
我们可以通过手动设置no_new_privs来确认此行为,然后再尝试执行权限提升:
|
|
容器运行时在创建新的容器化进程时会执行完全相同的操作。例如,这是runc中的容器初始化代码,被大多数容器运行时使用,如containerd、CRI-O和Docker:
|
|
那么问题是什么?
安全——就像大多数试图处理系统性故障的学科一样,是关于构建不同层次以确保单个缺陷不会变成数据泄露。
在这种情况下:是的,显式关闭allowPrivilegeEscalation是一种合法的良好安全加固实践。关闭它可以大大增加信心,即攻击者危害非特权应用程序无法在容器内将其权限提升到root,从而降低利用需要root权限的进一步漏洞的风险。
如果您没有在工作负载上关闭它,是否很糟糕?可能不是。将其视为您尚未启用的(又一个)加固机制。这不是会让您被黑客攻击的原因。除非您是一个成熟的安全团队,否则您最好首先专注于容器安全路线图中更高价值的项目。
也就是说,这不是一个您应该忽略的设置;确保它是您容器安全路线图的一部分。
常见问题解答
allowPrivilegeEscalation的默认值是什么? 默认值为true。
如果我的工作负载在容器内以root身份运行,关闭allowPrivilegeEscalation有什么意义吗? 没有,完全没有意义。如果您的工作负载以root身份运行,它们在容器内无法实现进一步的权限提升。
如果我的工作负载以"privileged"运行或具有CAP_SYS_ADMIN能力,关闭allowPrivilegeEscalation有什么意义吗? 没有意义。事实上,您甚至无法这样做——API服务器将拒绝您的请求。
关闭allowPrivilegeEscalation可以防止容器内的所有类型的权限提升吗? 不可以。例如,如果攻击者利用允许他们提升权限的内核缺陷,它将无济于事。也就是说,它应该阻止所有通过利用setuid/setgid工作的权限提升。
allowPrivilegeEscalation和privileged之间有什么联系吗? 没有。关闭allowPrivilegeEscalation是一种安全加固机制。如果您将其保留为默认值,容器内的进程仍然不能轻易提升其权限,也不能逃逸容器。启用privileged运行工作负载使它们像直接在主机上的进程一样运行,使得容器逃逸变得微不足道。
如果攻击者成功在容器内提升到root,难道不是世界末日吗? 又一个误解,有时由推动安全行业的FUD愉快地传播。在容器内以root身份运行的进程不能轻易逃逸到外部。它将不得不利用另一个漏洞或错误配置。
结论
希望本文提供了关于’allowPrivilegeEscalation’是什么、不是什么以及使用它的明显好处的更深入概述。当我第一次发现它时,我自己也感到困惑,由于它不幸的命名,它似乎是许多人困惑的根源。