通过 sudo 安全地使用 find

通过 sudo 安全地使用 find

在 Linux 服务器上,我需要删除一组用户的 root 权限。但这些用户有正当理由使用“find”实用程序根据文件名、修改日期和其他元数据搜索文件。

在服务器上,文件名并不敏感,但文件内容可能是敏感的。

我想使用 sudo 来允许用户在服务器上的任何位置搜索文件。“find”实用程序很棒,但它会产生各种副作用,例如使用“-exec”生成任意命令。

我能find在有限制的情况下继续工作吗?

答案1

关于什么定位

定位读取一个或多个由 updatedb(8) 准备的数据库,并将与至少一个 PATTERN 匹配的文件名写入标准输出,每行一个。如果未指定 --regex,PATTERN 可以包含通配符。如果任何 PATTERN 不包含通配符,定位的行为就像模式是图案

默认情况下,locate 不会检查数据库中找到的文件是否仍然存在。locate 永远无法报告相关数据库最近更新后创建的文件。

或者甚至定位

Secure Locate 提供了一种安全的方式来索引和快速搜索系统中的文件。它使用增量编码(就像 GNU 定位一样)来压缩其数据库以加快搜索速度,但它也会存储文件权限和所有权,以便用户不会看到他们无权访问的文件。

本手册页记录了 slocate 的 GNU 版本。slocate 使系统用户能够搜索整个文件系统而不显示未经授权的文件。

答案2

根据man 7 capabilities

   CAP_DAC_READ_SEARCH
          * Bypass file read permission checks and directory read and execute permission checks;
          * Invoke open_by_handle_at(2).

这对我有用。(以“#”开头的行是root,以“$”开头的行是非root)在这种情况下,非root用户在组中wheel

# cp /usr/bin/find /usr/bin/sudofind
# chmod 710 /usr/bin/sudofind
# chown root:wheel /usr/bin/sudofind
# setcap cap_dac_read_search+ep /usr/bin/sudofind
# exit
$ find /root 
find: ‘/root’: Permission denied
$ sudofind /root
/root /root 
/root/Testbed 
...
... 
$ sudofind /root -exec cat {} \;
cat: /root: Permission denied 
cat: /root/Testbed: Permission denied
$ sudofind /root -printf "%u %g %m %c %p\n"
root root 644 Mon Apr 20 09:20:48.0457518493 2015 /root
root root 755 Fri Dec  4 02:34:03.0016294644 2015 /root/Testbed
...
...
$ # Capability inheritance test..
$ sudofind /root -exec /bin/sleep 10 \; &
[1] 17017
$ getpcaps $(pgrep find)
Capabilities for `17017': = cap_dac_read_search+ep
$ getpcaps $(pgrep sleep)
Capabilities for `17019': =

考虑到该功能授予的内容,它完全符合您的要求。我还没有详尽检查是否find有允许您读取文件内部字节的功能,但LD_PRELOAD由于 Linux 中 setuid 检查的性质,像库填充攻击这样的明显的东西不应该起作用,而且功能位也不会被子进程继承(与原始 setuid 不同),所以这是另一个好处。

请记住,您想要做的事情确实会引发与临时文件创建或访问有关的隐私问题,并且该程序可用作安装竞争条件/权限提升尝试的基础(针对创建众所周知文件名但不进行正确安全检查的程序)。

此外,一些编写不佳的应用程序可能会依赖文件元数据或树结构来传达含义或隐藏数据。这可能会导致泄露受限制的信息或泄露原本不为人知的特权文档(我知道通过隐蔽性来实现安全性,但不幸的是,这是闭源供应商特别喜欢做的事情)。

因此,在做这件事时要小心谨慎,并要明白即使显而易见的事情不起作用,仍然存在相关风险。

哦,我很想知道是否有人有概念验证攻击,该攻击使用这种机制作为权限提升的基础!

答案3

我会给予用户适当的权限。

默认情况下,如果 umask 为022,则创建目录以便每个人都可以列出和统计其中的文件。如果不是,您可以手动将目录的权限更改为其旧权限的按位或0555

chmod +0555 foo

如果这些用户对该目录的所有父目录(例如,另一个用户的主目录)没有执行权限,则可能意味着您应该将第一个目录放在其他地方。

如果你只想让某些用户读取和执行该目录,你可以将其模式更改为0750,将这些用户放在一个组中,并将目录的组所有者更改为该组:

groupadd can_read_foo
chmod 0750 foo
chgrp can_read_foo foo
gpasswd -a alice can_read_foo
gpasswd -a bob can_read_foo

相关内容