在 的手册页末尾sudo
,有以下注释:
Running shell scripts via sudo can expose the same kernel bugs that
make setuid shell scripts unsafe on some operating systems (if your OS
has a /dev/fd/ directory, setuid shell scripts are generally safe).
该段落中的几乎所有内容对我来说都是晦涩难懂的。我特别想知道这个典故到底/dev/fd
是关于什么的。我试图猜测一些可能的手册页,我可以在其中找到这些信息,但我一无所获。
有什么建议么?
(最终我想通过 cron 在 sudo 下运行一些脚本,如果可能的话,但当然我担心这种无人监督的安排中可能存在的安全漏洞。)
答案1
我不明白这如何适用于sudo
.
对于 setuid 脚本,其想法是这样的:
假设您有一个/usr/local/bin/myscript
setuid root 并以 开头#! /bin/sh
。没有人有/usr/local/bin
或的写权限myscript
,但任何人都可以这样做:
ln -s /usr/local/bin/myscript /tmp/-i
并且/tmp/-i
也成为 setuid 脚本,即使您仍然没有对它的写访问权限,但您确实对/tmp
.
在 setuid 脚本不通过 执行的系统上/dev/fd
,当您执行 时cd /tmp && -i
,setuid 位意味着它将/bin/sh -i
以 root 身份运行:
- 该进程将 euid 更改为文件所有者
- 系统解析shebang
- 系统执行(仍以root身份),
/bin/sh -i
现在,对于这种特殊情况,简单的解决方法是按照推荐的方式编写 shebang:#! /bin/sh -
,但即便如此,仍然存在竞争条件。现在变成:
- 该进程将 euid 更改为文件所有者
- 系统解析shebang
- 系统执行(仍以root身份),
/bin/sh - -i
- “sh”打开当前目录中的“-i”文件(你会认为很好)。
但是在上面的 3 和 4 之间,您有足够的时间将“-i”或(“any-file”,因为它是这里的不同攻击向量)更改为某些邪恶的例如,“-i”文件仅包含“sh”,您将获得一个 root shell(用于 setuid root 脚本)。
对于旧版本的ksh
,您甚至不需要这样做,因为在 4 中,ksh 首先在 中查找“-i” $PATH
,因此足以将您的邪恶的“-i” in $PATH
(ksh
将打开该文件而不是/tmp
)中的文件。
如果当您执行以下操作时,所有这些攻击向量都会被修复:cd /tmp; -i
系统会执行以下操作(仍在 execve 系统调用中):
- 原子地:找出文件是 setuid 并在
x
进程的某个文件描述符上打开该文件。 - 处理文件所有者的 euid 更改。
- 跑步
/bin/sh /dev/fd/x
sh
打开/dev/fd/x
它只能引用d 的文件execve
。
关键是该文件作为 execve 的一部分打开,因此我们知道它是包含可信内容的代码,将使用更改后的权限进行解释。
现在这不适用于,sudo
因为该sudo
策略基于path
.
如果sudo
规则规定您可以以 root 身份运行 /usr/local/bin/myscript,那么您可以执行以下操作:
sudo /usr/local/bin/myscript
但你不能这样做:
sudo /tmp/any-file
即使“任何文件”是到/usr/local/bin/myscript
.sudo
不使用/dev/fd
AFAICT。