`ln /path/to/file -i` 在 setuid 脚本中做什么?

`ln /path/to/file -i` 在 setuid 脚本中做什么?

我正在制作一个带有 setuid 权限的 Bash 脚本,但它不起作用。所以我在这里找到了我的解决方案:

现在我的脚本工作正常(我用 cpp 重写了它)。

为了满足我对为什么纯 Bash shell 不起作用的好奇心,我阅读了以下链接:http://www.faqs.org/faqs/unix-faq/faq/part4/section-7.html(参考这个答案:https://unix.stackexchange.com/a/2910)。在那个网站上,我发现了以下内容:

        $ echo \#\!\/bin\/sh > /etc/setuid_script
        $ chmod 4755 /etc/setuid_script
        $ cd /tmp
        $ ln /etc/setuid_script -i
        $ PATH=.
        $ -i

我不明白第四行,它写着ln /etc/setuid_script -i

该命令有什么作用?

我在手册中读到ln-i只是“交互式”标志(询问您是否要覆盖现有文件)。那么为什么ln /etc/setuid_script -i后面跟着PATH=.and-i会让我的 shell 执行/bin/sh -i呢?

答案1

该代码ln /etc/setuid_script -i旨在创建指向-i当前目录中调用的文件的硬链接。如果您使用的是 GNU 工具,您可能需要说ln -- /etc/setuid_script -i要使其工作。

shell 可以通过 3 种不同的方式获取命令来运行。

  1. 来自字符串。sh -c "mkdir /tmp/me"与标志一起使用-c
  2. 来自一个文件。使用sh filename
  3. 在终端中,使用sh -ish

foo从历史上看,当您有一个名为“从#!/bin/sh内核开始”的 shell 脚本时,会使用文件名(即 )调用/bin/sh foo它,告诉它使用第二种读取命令的方式。如果你给它一个文件名,-i那么内核就会调用/bin/sh -i,你就会得到第三种方式。

还有竞争条件。这就被利用了。

  1. 调用系统exec调用来启动脚本。
  2. 内核看到该文件是SUID,并相应地设置进程的权限。
  3. 内核读取文件的前几个字节以查看它是什么类型的可执行文件,找到#!/bin/sh并因此认为它是 /bin/sh 的脚本。
  4. 攻击者替换了脚本。
  5. 内核将当前进程替换为/bin/sh。
  6. /bin/sh 打开文件名并执行命令。

这是经典TOCTTOU(检查时间到使用时间)攻击。步骤 2 中的检查针对的是与步骤 6 中(在 open 调用中)使用的文件不同的文件。

这两个错误现在通常都已得到修复。

答案2

您链接到的文档(http://www.faqs.org/faqs/unix-faq/faq/part4/section-7.html)正在描述(可能是)UNIX 系统上的行为ln,并且您查看了 Linux 系统(或更准确地说是 GNU/Linux)中的手册。 GNU 是这里的相关部分。 GNUln确实有你提到的选项:

   -i, --interactive
          prompt whether to remove destinations

然而,这是一个 GNU 扩展,不属于POSIX标准其中仅定义了以下选项标志:

-f
    Force existing destination pathnames to be removed to allow the link.
-L
    For each source_file operand that names a file of type symbolic link, create a (hard) link to the file referenced by the symbolic link.
-P
    For each source_file operand that names a file of type symbolic link, create a (hard) link to the symbolic link itself.
-s
    Create symbolic links instead of hard links. If the -s option is specified, the -L and -P options shall be silently ignored.

因此,由于-i不是 的有效选项ln,该命令ln /etc/setuid_script -i实际上会创建一个名为 的硬链接,-i该链接指向/etc/setuid_script。接下来,该命令PATH=.重新定义PATH变量以仅搜索当前目录中的可执行文件,这意味着将执行当前目录中-i指定的文件,因为它是 的硬链接,所以将执行脚本。但是,由于这是一个 shell 脚本,因此实际运行的命令将是.-i/etc/setuid_script/bin/sh -i

相关内容