基于 Linux 的系统很容易受到非特权 UID 进程的符号链接竞争攻击。为了例子,共享主机上的 PHP 进程可以在目录中创建指向 /etc/passwd 的符号链接,Apache httpd 将在该目录中向 Internet 上的任何人提供该符号链接。有关符号链接相关问题的其他示例,请参阅
https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=linux+symlink+race
我想要某种方法来保护所有 Linux 系统(各种版本)免受那些可疑进程创建恶意符号链接的影响。
有一些部分解决方案,但通常它们涉及 Linux 内核的自定义修补(这是一项繁重的工作,并且会拖累更新过程),或者它们的限制性不够。 Linux 3.6 及更高版本中有 Kees Cook 的补丁
但它并不存在于所有早期的 Linux 版本中,并且它仅可以防止某些符号链接问题,而不一定是所有问题(例如在非粘性位目录中创建符号链接,这仍然是一个问题)。
从 2.6.26 版本开始,适用于所有常见 Linux 系统的符号链接竞争漏洞通用解决方案有哪些?
我想到的一件事是建立一个全局规则来阻止高 UID 用户创建符号链接。对于某些部署(共享托管),此类限制可能是可以接受的。
禁止用户在 Linux 内核 >=2.6.26 的系统上创建符号链接的最简单方法是什么?(但是,需要更多特权用户支持符号链接,包括 root)
SELinux、Seccomp-bpf、Apparmor 中哪一个最适合设置此类限制?
答案1
阻止 Apache 创建符号链接可能不会破坏它。
在当前的Linux,有两个系统调用可以创建新的符号链接:symlink
和symlinkat
。
man systemd.exec
告诉我们 systemd 可以安装 seccomp 过滤器,以拒绝某些系统调用:SystemCallFilter=~symlink symlinkat
。根据man systemd.unit
,现有的 systemd 服务文件可以使用“插入”文件进行修改,例如/etc/systemd/system/httpd.service.d/nosymlink.conf
.
编辑:当然,如果您在单独的 systemd 服务中将 PHP 作为 FastCGI 运行,那么您需要修改该服务而不是httpd
.
这种“黑名单”方法有一个巨大的警告:
将操作系统升级到新内核可能会增加对新系统调用的支持。不幸的是,即使是较新的版本也symlinkat()
没有添加标志参数。因此,如果symlinkat
需要以任何方式修改 的行为,将来可能需要添加新的系统调用。讽刺的是,最可能的原因是为了添加AT_BENEATH支持symlinkat
。这可能会重新打开“漏洞”,例如,如果较新版本的 GNU libc 通过新的symlinkat2()
系统调用来收集所有符号链接的创建。
答案2
您可以在 Linux 中使用不可变位选项。
具有不可变属性的文件不能是:
- 修改的
- 已删除
- 更名
- 任何人(包括 root 用户)都不会创建软链接或硬链接
使用chattr(检查您的操作系统是否支持)命令来设置属性。
chattr +i file
chattr +i /path/to/filename
列出文件wrt属性位的属性
lsattr /etc/shadow
要删除不可变位:
chattr -i file
chattr -i /path/to/filename
答案3
如果你想禁止 PHP 读取 /etc/passwd,那么你必须已经禁止它执行任意命令。
那么你已经知道如何禁止它调用了symlink()
。
我注意到 PHP 已经弃用并删除了“安全模式”,并且仍然没有官方的使用指南disable_functions
。