特权容器逃逸 - 控制组release_agent技术分析
背景介绍
在容器化环境中进行漏洞挖掘时,一个常见主题是从容器逃逸到主机执行代码。本文将深入分析Felix Wilhelm(@_fel1x)报告的一种技术,通过滥用控制组(cgroups)的release_agent功能,从特权容器逃逸并在容器主机上执行任意命令。
特权容器的风险
特权容器通常用于CI/CD流水线中,以允许构建和发布Docker镜像。虽然攻破特权容器让攻击者更接近容器主机,但通常不能直接在主机上执行命令。
原始PoC技术原理
2019年7月,Felix Wilhelm发布了一个概念验证(PoC),展示了如何利用cgroups release_agent功能逃逸特权容器:
cgroups release_agent功能可以从特权容器触发,执行主机文件系统上的路径,该路径由release_agent文件的内容指定。关键在于release_agent文件中指定的路径必须相对于容器主机的根文件系统,而不是容器。
Felix的PoC通过解析容器根挂载点并提取upperdir挂载选项来识别容器内文件的主机路径。对于使用overlayfs的容器,这会暴露容器挂载的主机文件系统路径。
边缘场景处理
原始PoC在容器配置为使用暴露完整主机挂载点路径的存储驱动程序(如overlayfs)时工作良好,但某些配置不会明显披露主机文件系统挂载点:
Kata容器:默认通过9pfs挂载容器根文件系统,不披露容器文件系统在Kata容器虚拟机中的位置。
设备映射器:某些devicemapper存储驱动程序配置可能只显示设备路径(如/dev/sdc),而不显示完整的主机路径。
替代PoC方案
在这些情况下,原始PoC无法直接使用,但通过一些技巧仍然可以执行此攻击。
/proc文件系统利用
Linux的/proc伪文件系统暴露系统上所有进程的内核进程数据结构,包括在不同命名空间(如容器内)运行的进程。
关键发现:/proc/<pid>/root
符号链接可以用作主机相对路径来访问容器内的任何文件。这改变了攻击要求,从需要知道容器内文件的完整主机相对路径,变为只需要知道容器内运行的任何进程的pid。
PID暴力破解技术
由于Linux进程ID是数字且顺序分配的,可以使用暴力增量搜索来识别容器内进程的主机进程ID:
|
|
完整攻击实现
结合这些技术,可以创建一个比Felix原始PoC更通用的攻击方案:
- 准备要在主机上执行的有效载荷脚本
- 设置使用内存资源cgroup控制器的cgroup挂载
- 使用暴力破解技术猜测pid路径
/proc/<pid>/root/payload.sh
- 每次迭代将猜测的pid路径写入cgroups release_agent文件
- 触发release_agent执行,检查是否创建了输出文件
注意事项:此技术并不隐蔽,可能会显著增加pid计数,但由于没有保持长时间运行的进程,应该不会引起可靠性问题。
PoC脚本详解
提供的PoC脚本实现了以下功能:
|
|
执行结果
在特权容器内执行PoC脚本将提供类似以下的输出,显示主机上的所有进程信息,证明已成功逃逸到主机执行命令。
总结
感谢Felix Wilhelm发布了这种强大的特权容器逃逸技术的初始PoC。这种技术展示了容器安全中的关键漏洞,强调了正确配置容器权限的重要性。
有关cgroups release_agent工作原理的更多详细信息,请参阅内核文档。