Board logo

标题: 安全编程 避免竞争条件 资源争用可能对您不利(2) [打印本页]

作者: look_w    时间: 2018-4-18 21:19     标题: 安全编程 避免竞争条件 资源争用可能对您不利(2)

处理文件系统安全程序的编写必须确保攻击者无法以导致问题的方式利用共享的资源,有时这并不像看起来那样容易办到。文件系统是最常见的共享资源之一。所有的程序都可以共享文件系统,所以,有时需要额外的努力,以确保攻击者不能以引发问题的方式利用文件系统。
有很多确定为安全的程序都存在称为“time of check - time of use”(TOCTOU)的竞争条件缺陷。这只说明了程序检查某种情形是否可行,然后稍后使用那一信息,但是攻击者可能会在这两个步骤之间改变该情形。对文件系统来说,以下问题尤为突出;在这两个步骤之间,攻击者通常可以创建一个普通的文件或者一个符号链接。例如,如果某个已授予特权的程序检查是否不存在给定名称的文件,然后打开该文件写入信息,那么在那两个步骤之间,攻击者可以创建一个使用该名称的符号链接文件... 比如 /etc/passwd 或者其他一些敏感文件。
遵守一些简单的规则,可以避免这些问题:
如果可以,不要将文件放置在可以由不信任用户共享的目录中。如果不是那样,那么应该尽量不使用在用户间共享的目录。不要介意创建只能由受信任的特定进程访问的目录。
考虑避免使用传统的共享目录 /tmp 和 /var/tmp。如果您可以只使用一个管道,将数据从一个位置发送到另一个位置,那么您就可以简化程序,并排除潜在的安全问题。如果您确实需要创建一个临时文件,那么可以考虑将临时文件存储到其他地方。如果您不是在编写一个有特权的程序,那么这点尤其需要考虑;如果您的程序没有特权,那么将临时文件放置在用户目录内部会更安全一些(处理 root 用户时要当心,它以“/”作为其主目录)。这样,即使您没有“正确地”创建临时文件,攻击者通常也无法引发问题(因为攻击者不能利用用户主目录的内容)。
但是,无法总是能够避免使用共享目录,所以我们需要理解如何处理 /tmp 等共享目录。这一点非常复杂,所以它应该自己占用一节!
共享目录(比如 /tmp)共享目录基本概念如果您可信任的程序将要与潜在的非信任用户共享一个目录,那么要特别小心。在类 Unix 系统中,最常见的共享目录是 /tmp 和 /var/tmp,对这些目录的错误使用滋生了很多安全缺陷。最初创建 /tmp 目录,是将它作为一个创建临时文件的方便位置,通常不应该与任何其他人共享临时文件。不过,该目录很快它就有了第二个用途 —— 创建用户间共享对象的标准位置。由于这些标准目录有多种用途,使得操作系统难以加强访问控制来防止攻击;因此,您必须正确地使用它们,以避免受到攻击。
当您使用共享目录时,确保目录和文件有适当的权限。显然,您需要限制哪些人可以对共享目录中创建的文件进行读写操作。但是,在类 Unix 系统中,如果多个用户都可以向同一目录添加文件,而且您计划通过一个有特权的程序向该目录添加文件,那么要确保为该目录设置“sticky”位。在一个普通的目录中(没有 sticky 位),任何人对它都有写权限 —— 包括攻击者 —— 可以删除或者重命名文件,导致各种各样的问题。例如,一个可信任的程序可以在这样一个目录下创建一个文件,而一个不受信任的用户可以删除或者重命名它。在类 Unix 系统上,需要设置共享目录的“sticky”位;在 sticky 目录中,文件只能由 root 或者文件的所有者解除链接或者重新命名。/tmp 和 /var/tmp 目录通常实现为“sticky”目录,以排除一些问题。
程序有时会留下一些没用的临时文件,所以,大部分类 Unix 系统会自动删除特定目录 /tmp 和 /var/tmp 下的原有临时文件(“tmpwatch”程序可以完成这项任务),一些程序会“自动”删除它们所使用的特定临时目录下的文件。这听起来很方便...只可惜攻击者可能会让系统特别繁忙,使        活动文件成为旧文件。结果:系统可能会自动删除正被使用的文件名称。然后会发生什么?攻击者可能会尝试创建他们自己的相同名称的文件,或者至少让系统创建另一个进程,并重新使用相同的文件名称。结果:混乱。这类问题叫做“tmpwatch”问题。解决这种问题的方法是,一旦自动创建了一个临时文件,就必须始终使用打开该文件时得到的文件描述符或文件流。永远不要重新打开文件或者使用任何以文件为参数的操作 —— 始终使用文件描述符或者相关的流,否则,tmpwatch 竞争将引发一些问题。您甚至无法先创建文件、然后关闭它、然后再重新打开它,即使权限已经限制了谁可以打开该文件。      
攻击 sticky 目录以及您创建的文件的受限权限只是第一步。在运行安全程序期间,攻击者可能会尝试进行插入操作。常见的一种攻击是,当您的程序正在运行时,在共享目录中创建和反创建指向其他一些文件的符号链接 —— /etc/passwd 或者 /dev/zero 是常见的目标。攻击者的目标是,创造这样一种情形,即让安全程序判定某个给定的文件名并不存在,然后,攻击者就可以创建指向另一个文件的符号链接,而后安全程序继续执行某些操作(但是现在,它打开的实际上是一个意料之外的文件)。重要的文件经常会被这样破坏或更改。这种做法的另一个变种是,创建和反创建攻击者可以进行写操作的普通文件,这样,攻击者有时就可以控制有特权的程序创建的“内部”文件。
在这些共享目录中创建文件时,常遇见的一个问题是,您必须确保您计划使用的文件名在创建时并不存在,然后自动创建该文件。在创建该文件“之前”进行检查没有用,因为在已经进行了检查但还没有创建该文件之前,另一个进程可以使用该文件名创建出这个文件。使用“不可预知的”或者“惟一的”文件名也没有用,因为攻击者可以反复猜测该文件名,直到成功为止。所以,您需要执行一个或者创建一个新文件或者失败的操作 —— 不做其他任何事情。类 Unix 系统可以这样做,但是您需要知道如何要求系统去做。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0