Bil*_*lly 6 setuid sudo shell-script
sudo
启动时被提升为 root,因为它的二进制文件已setuid
启用。但是,当我赋予/bin/login
确切的权限时sudo
,并尝试从非 root 用户运行它时,出现错误:
No utmp entry. You must exec "login" from the lowest level "sh"
Run Code Online (Sandbox Code Playgroud)
我的第一个问题是,这个错误是什么意思?我的第二个是,为什么当我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
Run Code Online (Sandbox Code Playgroud)
所以我有三个问题:
login
?login
与sudo
?whoami
不起作用?我得到的错误是什么
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);
}
Run Code Online (Sandbox Code Playgroud)
有趣的部分是最后的 if 子句。getuid()
如果不为 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 的脚本。然后,攻击者可以创建指向该脚本的符号链接,调用该脚本,然后在解释器打开符号链接后面的脚本(当时是邪恶的)之前,将符号链接更改为他的脚本。