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
所以我有三个问题:
- 我遇到的错误是什么
login
? - 为什么
login
与 一起工作sudo
? - 为什么我的简单运行脚本
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 的脚本。然后,攻击者可以创建到该脚本的符号链接,调用该脚本,然后在解释器打开符号链接后面的脚本(这就是邪恶的脚本)之前将符号链接更改为他的脚本。