保护 Linux 系统免受符号链接攻击

保护 Linux 系统免受符号链接攻击

基于 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 的补丁

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=800179c9b8a1e796e441674776d11cd4c05d61d7

但它并不存在于所有早期的 Linux 版本中,并且它仅可以防止某些符号链接问题,而不一定是所有问题(例如在非粘性位目录中创建符号链接,这仍然是一个问题)。

从 2.6.26 版本开始,适用于所有常见 Linux 系统的符号链接竞争漏洞通用解决方案有哪些?

我想到的一件事是建立一个全局规则来阻止高 UID 用户创建符号链接。对于某些部署(共享托管),此类限制可能是可以接受的。

禁止用户在 Linux 内核 >=2.6.26 的系统上创建符号链接的最简单方法是什么?(但是,需要更多特权用户支持符号链接,包括 root)

SELinux、Seccomp-bpf、Apparmor 中哪一个最适合设置此类限制?

答案1

阻止 Apache 创建符号链接可能不会破坏它。

当前的Linux,有两个系统调用可以创建新的符号链接:symlinksymlinkat

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 中使用不可变位选项。

具有不可变属性的文件不能是:

  1. 修改的
  2. 已删除
  3. 更名
  4. 任何人(包括 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

相关内容