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

Kri*_*ian 2 bash setuid ln

我正在制作一个具有 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
Run Code Online (Sandbox Code Playgroud)

我不明白第四行,它是ln /etc/setuid_script -i.

这个命令有什么作用?

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

ica*_*rus 5

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

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 调用中)不同的文件。

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