sudo 如何工作(除了 setuid)?

sudo 如何工作(除了 setuid)?

sudo在启动时被提升为 root,因为它的二进制文件已setuid启用。但是,当我给出/bin/login确切的权限sudo并尝试从非 root 用户运行它时,我收到错误:

No utmp entry.  You must exec "login" from the lowest level "sh"

我的第一个问题是,这个错误是什么意思?我的第二个问题是,为什么当我sudo login从同一用户运行时它会起作用?除了使用 asetuuid提升到 root 之外,还有什么作用sudo?我编写了一个简单的dash脚本来~/root运行whoami和退出,但它返回我的非特权用户的用户名。

$ ls -l ./root /usr/bin/sudo
-rwsr-xr-x 1 root root     29 Jul 15 02:40 ./root
-rwsr-xr-x 1 root root 157760 Jan 10  2016 /usr/bin/sudo

$ ./root
unprivileged user

所以我有三个问题:

  1. 我遇到的错误是什么login
  2. 为什么login与 一起工作sudo
  3. 为什么我的简单运行脚本whoami不起作用?

答案1

我遇到的错误是什么login

在搜索源码时login,我们看到了这样一段话:

amroot = (getuid () == 0);
[...]
utent = get_current_utmp ();
/*
 * Be picky if run by normal users (possible if installed setuid
 * root), but not if run by root. This way it still allows logins
 * even if your getty is broken, or if something corrupts utmp,
 * but users must "exec login" which will use the existing utmp
 * entry (will not overwrite remote hostname).  --marekm
 */
if (!amroot && (NULL == utent)) {
     (void) puts (_("No utmp entry.  You must exec \"login\" from the lowest level \"sh\""));
     exit (1);
}

有趣的部分是最后的 if 子句。当getuid()is 不为 0 且没有 utmp 条目时,将出现该错误消息。getuid()返回真实用户ID的调用过程。如果您login在调用时设置了 setuid 标志,则实际 uid 和有效 uid 会有所不同。login正如源代码片段中的评论所暗示的那样,在这种情况下“挑剔”:它失败并抛出提到的错误。


为什么login与 一起工作sudo

sudo本身设置了 setuid 位,因此 euid 和 ruid 有所不同。但是,sudo 执行二进制文件login并将真实和有效的 uid 设置为目标用户。因此它不会再失败了。


为什么我的简单运行脚本whoami不起作用?

#!您的脚本中有一个 shebang 行 ( ) (我认为)。发生的情况如下:内核打开可执行文件(在您的情况下是文本文件)并观察#!.调用 shebang 行中给出的解释器(例如/bin/bash/bin/sh),并将脚本名称作为第一个参数,而不是文本文件。大多数 UNIX 和 Linux 操作系统在对脚本进行设置时会忽略 setuid 位,因为这是一个安全问题。

想象一下设置了 setuid 的脚本。然后,攻击者可以创建到该脚本的符号链接,调用该脚本,然后在解释器打开符号链接后面的脚本(这就是邪恶的脚本)之前将符号链接更改为他的脚本。

相关内容