3

任何人都可以指出一些通过环境变量(部分)指定的路径处理文件访问安全性的代码,特别是对于 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 目前的行为与描述的一样,并且是一个大型程序包(数百万行代码,十多年来针对各种编码标准开发,无论如何这些标准经常被忽略),您将使用什么技术来修复问题?

已知的选项包括:

  1. 更改所有格式化调用以使用根据格式字符串检查实际参数的函数,并使用一个额外的参数指示传递给函数的实际类型。(这很棘手,并且由于要更改的格式操作数量众多,因此可能容易出错 - 但如果检查功能本身是合理的,则效果很好。)
  2. 建立到 PQRHOME 的直接路径并验证它的安全性(详细信息如下),如果它不安全,则拒绝启动,然后使用直接路径而不是 $PQRHOME 的值(当它们不同时)。(这要求所有使用 $PQRHOME 的文件操作不使用来自 getenv() 的值,而是使用映射路径。例如,这将要求软件确定 /home/attacker/pqr 是 /opt/pqr 的符号链接, /opt/pqr 的路径是安全的,此后,每当文件被引用为 $PQRHOME/some/thing 时,使用的名称将是 /opt/pqr/some/thing 而不是 /home/attacker/pqr/some /thing。这是一个大型代码库 - 修复起来并不简单。)
  3. 确保 $PQRHOME 上的所有目录,甚至通过符号链接进行跟踪,都是安全的(再次详细说明如下),如果有任何不安全的地方,软件将拒绝启动。
  4. 硬编码软件安装位置的路径。(这对 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 访问;这不是远程攻击。它需要大量的知识才能到达那里,但我认为假设专业知识不“在那里”是不明智的。

所以,我所描述的是一个“格式字符串漏洞”,已知的攻击路径涉及伪造程序,因此尽管它认为它正在访问安全的消息文件,但它实际上会使用消息文件(其中包含格式字符串)受用户控制,不受软件控制。

4

2 回答 2

2

$PQRHOME如果您在解析其真实路径并检查其安全性后写入新值,则选项 2 有效。这样一来,您的代码几乎不需要更改。

就保持 setuid 权限而言,如果您可以进行某种权限分离会有所帮助,以便涉及来自真实用户的输入的任何操作在真实 uid 下运行。然后特权进程和 real-uid 进程使用 asocketpair或类似的东西进行交谈。

于 2008-10-12T23:24:00.270 回答
1

好吧,这听起来很偏执,但是否如此取决于您的应用程序在哪个系统上运行以及攻击者可以造成哪些损害。

因此,如果您的用户群可能是敌对的,并且损坏可能非常高,我会选择选项 4,但进行如下修改以消除其缺点。

让我引用两个相关的事情:

1)

程序当前检查 $PQRHOME 及其下的关键目录是否“安全”(由 pqrusr 拥有,属于 pqrgrp,没有公共写访问权限)。

2)

此后,程序通过环境变量的完整值访问 $PQRHOME 下的文件。

您实际上不需要硬编码完整路径,您可以仅硬编码从 1) 中提到的“程序”到 2) 中提到的文件所在路径的相对路径。

要控制的问题:

a)您必须确保在可执行文件的路径和文件的路径之间没有任何“攻击者可访问”(例如,在符号链接方面)

b)您必须确保可执行文件以可靠的方式检查自己的路径,但这在我所知道的所有 Unix 中都不应该是一个问题(但我不知道所有的 'em 并且我不知道 windows完全)。


在第三条评论后编辑:

如果您的操作系统支持 /proc,则 syslink /proc/${pid}/exe 是解决问题的最佳方法 b)


睡后编辑:

安装是一个“安全”的过程吗?如果是这样,您可以(在安装时)创建一个包装脚本。该脚本应该是可执行的但不可写(并且可能既不可读)。它会将 $PQRHOME 环境变量设置为“安全”值,然后调用您的实际程序(它最终也可能会做其他有用的事情)。由于在 UNIX 中,除了正在运行的进程之外,其他任何东西都不能更改正在运行的进程的环境变量,因此您是安全的(当然,父进程可以在进程启动之前更改环境变量)。不过,我不知道这种方法是否适用于 Windows。

于 2008-10-13T19:29:21.180 回答