任何人都可以指出一些通过环境变量(部分)指定的路径处理文件访问安全性的代码,特别是对于 Unix 及其变体,但 Windows 解决方案也很有趣?
这是一个很长的问题-我不确定它是否适合 SO 范式。
考虑这种情况:
背景:
- 软件包 PQR 可以安装在用户选择的位置。
- 环境变量 $PQRHOME 用于标识安装目录。
- 默认情况下,$PQRHOME 下的所有程序和文件都属于一个特殊的组 pqrgrp。
- 同样,$PQRHOME 下的所有程序和文件要么属于特殊用户 pqrusr,要么属于用户 root(这些是 SUID 根程序)。
- 一些程序是 SUID pqrusr;还有几个程序是 SGID pqrgrp。
- 大多数目录归pqrusr所有,属于pqrgrp;有些可以属于其他组,并且这些组的成员获得使用该软件的额外权限。
- 许多特权可执行文件必须由不是 pqrgrp 成员的人运行;程序必须通过不直接涉及此问题的神秘规则验证是否允许用户运行它。
- 启动后,一些特权程序必须保留其提升的特权,因为它们是长期运行的守护程序,可能在其生命周期内代表许多用户进行操作。
- 由于各种神秘的原因,这些程序无权将目录更改为 $PQRHOME。
当前检查:
- 程序当前检查 $PQRHOME 及其下的关键目录是否“安全”(由 pqrusr 拥有,属于 pqrgrp,没有公共写访问权限)。
- 此后,程序通过环境变量的完整值访问 $PQRHOME 下的文件。
- 特别是,G11N 和 L10N 是通过访问“安全”目录中的文件,并使用从 $PQRHOME 派生的完整路径名加上已知的子结构(例如,$PQRHOME/g11n/en_us/messages.l10n)。
假设 $PQRHOME 的“已安装”值为 /opt/pqr。
已知攻击:
- 攻击者设置 PQRHOME=/home/attacker/pqr。
- 这实际上是 /opt/pqr 的符号链接,因此当其中一个 PQR 程序称为 pqr-victim 检查目录时,它具有正确的权限。
- 安全检查成功完成后,攻击者立即更改符号链接,使其指向/home/attacker/bogus-pqr,这显然在攻击者的控制之下。
- 当 pqr-victim 现在访问所谓的安全目录下的文件时,可怕的事情就会发生。
鉴于 PQR 目前的行为与描述的一样,并且是一个大型程序包(数百万行代码,十多年来针对各种编码标准开发,无论如何这些标准经常被忽略),您将使用什么技术来修复问题?
已知的选项包括:
- 更改所有格式化调用以使用根据格式字符串检查实际参数的函数,并使用一个额外的参数指示传递给函数的实际类型。(这很棘手,并且由于要更改的格式操作数量众多,因此可能容易出错 - 但如果检查功能本身是合理的,则效果很好。)
- 建立到 PQRHOME 的直接路径并验证它的安全性(详细信息如下),如果它不安全,则拒绝启动,然后使用直接路径而不是 $PQRHOME 的值(当它们不同时)。(这要求所有使用 $PQRHOME 的文件操作不使用来自 getenv() 的值,而是使用映射路径。例如,这将要求软件确定 /home/attacker/pqr 是 /opt/pqr 的符号链接, /opt/pqr 的路径是安全的,此后,每当文件被引用为 $PQRHOME/some/thing 时,使用的名称将是 /opt/pqr/some/thing 而不是 /home/attacker/pqr/some /thing。这是一个大型代码库 - 修复起来并不简单。)
- 确保 $PQRHOME 上的所有目录,甚至通过符号链接进行跟踪,都是安全的(再次详细说明如下),如果有任何不安全的地方,软件将拒绝启动。
- 硬编码软件安装位置的路径。(这对 PQR 不起作用;如果不出意外的话,它会使测试变得很糟糕。对于用户来说,这意味着他们只能安装一个版本,并且升级等需要并行运行。这不适用于 PQR。)
安全路径的建议标准:
- 对于每个目录,必须信任所有者。(理由:所有者可以随时更改权限,因此必须信任所有者不要随意更改破坏软件的安全性。)
- 对于每个目录,该组必须没有写入权限(因此该组的成员不能修改目录内容)或者该组必须是受信任的。(理由:如果组成员可以修改目录,那么他们可以破坏软件的安全性,因此他们必须无法更改它,或者必须信任他们不会更改它。)
- 对于每个目录,“其他人”必须对该目录没有写权限。
- 默认情况下,可以信任用户 root、bin、sys 和 pqrusr(其中 bin 和 sys 存在)。
- 默认情况下,可以信任 GID=0(也称为 root、wheel 或 system)、bin、sys 和 pqrgrp 的组。此外,拥有根目录的组(在 MacOS X 上称为 admin)是可以信任的。
POSIX 函数realpath()
提供映射服务,将 /home/attacker/pqr 映射到 /opt/pqr;它不进行安全检查,但只需要在已解析的路径上进行。
那么,以所有这些为背景,是否有任何已知的软件通过模糊相关的回转来确保其安全性?这是不是太偏执了?(如果是这样,为什么 - 你真的确定吗?)
编辑:
感谢您的各种评论。
@S.Lott:攻击(在问题中概述)意味着可以使至少一个 setuid 根程序使用(非特权)用户选择的格式字符串,并且至少可以使程序崩溃,因此很可能可以获得一个根壳。幸运的是,它需要本地 shell 访问;这不是远程攻击。它需要大量的知识才能到达那里,但我认为假设专业知识不“在那里”是不明智的。
所以,我所描述的是一个“格式字符串漏洞”,已知的攻击路径涉及伪造程序,因此尽管它认为它正在访问安全的消息文件,但它实际上会使用消息文件(其中包含格式字符串)受用户控制,不受软件控制。