【问题标题】:access() Security Holeaccess() 安全漏洞
【发布时间】:2011-12-17 00:46:51
【问题描述】:

我一直在做一些 shell 编写,遇到了一个建议 access() 检查文件是否存在、是否可以读取等。似乎超级容易实现并且比 stat() 更快。当我开始查看它的手册页时,我注意到不建议使用它,因为它可能导致安全漏洞。手册页是这样说的:

使用 access() 检查用户是否被授权,例如打开一个文件 在实际这样做之前使用 open(2) 创建一个安全漏洞, 因为用户可能会利用 检查并打开文件以对其进行操作。

有谁知道如何利用它,或者它是否仅与检查文件后使用 open() 有关?我知道很多人说要改用stat(),但是access() 很容易实现,尤其是对于我使用它的shell。

【问题讨论】:

  • 毋庸置疑,stat() 存在与上述 access() 引用中描述的相同类型的潜在安全漏洞。

标签: c security exploit


【解决方案1】:

模式好像是调用access()或者stat()来判断是否可以打开文件,如果有权限再打开。

相反,通常最好继续尝试打开它,然后检查尝试是否成功(如果不成功,为什么)。这避免了检查和尝试打开文件之间的时间间隔。

【讨论】:

  • 其实会成功的。 access() 允许以授权用户身份运行的服务器模拟非特权用户(例如:NFS 服务器,...),而不必为每个用户创建一个新进程。
【解决方案2】:

这是一场 TOCTOU 竞赛(检查时间到更新时间)。恶意用户可以将他有权访问的文件替换为指向access()open() 调用之间他无权访问的内容的符号链接。使用faccessat()fstat()。一般情况下,打开一个文件一次,然后对其使用f*() 函数(例如:fchown(),...)。

【讨论】:

  • faccessat() 非常棒。感谢您向我指出这一点。
  • faccessat 的 fd 参数是针对您打开的目录,而不是针对文件本身。 faccessat(2) 并不能帮助您避免刚才描述的确切 TOCTOU 攻击,尤其是。如果您使用 AT_FDCWD 使其行为与 access(2) 完全相同。如果您使用 dir fd,那么对该目录具有写权限的攻击者仍然可以正常攻击。 (而且你必须使用相对路径的 openat,而不是 open,以避免攻击者在路径中更早地改组符号链接)
  • 将他有权访问的文件替换为他无权访问的文件的符号链接不会以任何方式帮助恶意用户,因为无论如何都会在open 调用期间检查访问权限。并且替换行为可能需要自己的访问权限。
【解决方案3】:

我能想到的一件事,虽然它看起来很弱 - access() 使用真实的而不是有效的 uid 和 gid。这应该允许一个 setuid 程序(一个普通用户执行但获得所有者权限的程序)检查调用用户是否可以读取文件,以防止无意中让该用户访问他们应该无法读取的文件,也许通过使用一些符号链接或硬链接技巧。我找不到任何证据表明这是可能的,或者 stat() 不可能,但想象一下这种情况:

user executes program
program is setuid, immediately gets all privs of root
program checks file1 to ensure that user has access
file1 is a hardlink to file2, which user has access to
user changes file1 to hardlink to file3 (/etc/shadow or something like that)
program reads file1 and does something to it (print, convert, whatever)
user now has access to a file they shouldn't

【讨论】:

  • 这可能是手册页引用部分所设想的确切场景。 stat 易受完全相同的影响,即底层文件在检查和实际访问之间发生变化。
  • 看起来它必须是硬链接,因为软链接有自己的权限。您可以硬链接到您无权访问的文件吗?
  • 符号链接没有自己的权限......好吧,他们有,但是access 检查目标的权限,而不是符号链接的权限。
  • @JohnFlatness:每当您看到推荐的stat 而不是access 时,就会想到fstat。打开文件然后fstat返回句柄。
  • 为了让用户能够更改 file1,它必须已经可以访问它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-24
  • 1970-01-01
  • 1970-01-01
  • 2021-08-19
  • 2017-02-28
  • 2013-04-15
  • 2020-06-24
相关资源
最近更新 更多