使用sudo安全地使用find


10

在Linux服务器上,我需要从一组用户中删除root特权。但是这些用户有合理的理由能够使用“查找”实用程序根据文件名,修改日期和其他元数据搜索文件。

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

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

我可以find不受限制地工作吗?


14
通常,您希望文件名模式的搜索结果包含您实际上无法访问的文件。在这方面,您的要求有些奇怪。
HBruijn

2
没有人强迫您参与这个问题。我认为Server Fault的目的之一就是为各种情况提供论坛。
Troels Arvin

2
Server Fault不是论坛,并且尝试逆向心理学也不会改变HBruijn的观察的有效性(我敢肯定,这是为了帮助您)。
轨道轻度竞赛

Answers:


19

定位呢?

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

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

或者甚至slocate命令

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

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


好主意。我不知道为什么我没有想到这一点。但是,如果sudo规则允许用户运行任何“ locate”命令,恐怕“ -d”参数可能会以某种方式用于读取任意文件?
Troels Arvin

2
@TroelsArvin:locate不需要sudo;只有其updatedb工作需要特殊特权。因此,您的用户永远都不会正在运行或能够运行sudo locate
jwodder

1
@jwodder:在RHEL 7服务器上:假设用户u无权访问/ data / foo。在/ data / foo中,有一个文件“ somefile.csv”。现在,当您执行“ locate somefile.csv”时,“ locate”的输出将不包含/data/foo/somefile.csv -除非用户u通过sudo执行“ locate”。(使用“ --nofollow”参数无济于事。)
Troels Arvin

1
@TroelsArvin但-d标志仅设置数据库路径吗?也许我误会了你。
伦尼

21

根据 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检查的性质,诸如shim和库shim攻击之类的显而易见的东西不起作用,并且功能位无法获取由子进程继承(不同于原始setuid),所以这是另一个好处。

请记住,您要执行的操作确实会引起有关临时文件创建或访问的隐私问题,并且该程序可以用作装入竞争条件/特权提升尝试的基础(针对创建知名文件名的程序)但请勿进行正确的安全检查)。

同样,某些编写不佳的应用程序可能依赖于文件元数据或树结构来传达含义或隐藏数据。这可能会导致发布受限制的信息或泄露其他方面未知的特权文档(我知道通过默默无闻的安全性,但是不幸的是,这是闭源供应商特别喜欢做的事情)。

因此,请当心并警惕这样做,即使有明显的问题不起作用,也要理解与此相关的风险。

哦,我很想看看有人是否有概念验证攻击,将这种机制用作注释中特权提升的基础!


5
这确实看起来很有趣!
斯文

像这样?好吧,没有PoC,但仍然
Lenniey

我喜欢这个想法,但是它有一个很大的缺点:sudofind现在是一个二进制文件,不属于系统上任何软件(例如RPM)软件包的一部分。因此,如果发行版发出了“查找”补丁,那么sudofind将不会更新。
Troels Arvin

2
@TroelsArvin不一定是坏事。如果您要向不是为这些功能设计的现有实用程序中添加类似setuid的功能,则在验证更新后的实用程序可以与非标准组件安全使用之前,您不希望对基础实用程序进行任何更新能力。想象一下,在这种情况下,如果有更新可以find直接执行一些用户提供的代码,就像awk可以做到的那样。
安德鲁·亨利

4
我可以看到的最大问题是,不可搜索目录下的可写世界目录可以突然写入。
塔维安·巴恩斯

2

我会给用户适当的权限。

默认情况下,如果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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.