有些程序需要调用者通常没有的、范围严格受控的访问权限。对于可执行普通文件,set-user-ID 位可以让新进程获得文件所有者的用户 ID 作为有效用户 ID。随后,程序可以执行该身份获准的操作,同时保留调用者的信息。
权限 · 第 5 课
Setuid
学习 set-user-ID 模式位如何影响可执行程序,以及它为何需要谨慎的安全审查。
Setuid 并不是“以 root 身份运行”的通用指令。其效果取决于可执行文件的所有者、操作系统、文件系统和挂载选项,以及程序管理凭据的方式。
识别 Setuid
在使用 setuid passwd 可执行文件的系统上,长列表可能如下所示:
$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 68248 Jan 10 09:30 /usr/bin/passwd
所有者执行位置的小写 s 表示 setuid 和所有者执行都已设置。如果有 setuid 但没有所有者执行,ls -l 会在该位置显示大写 S。
不要假设每个发行版都有相同模式或认证设计。应检查实际系统,而不是依赖示例。
所有者执行位置的小写 s 表示什么?
理解凭据变化
当内核在执行时采用 setuid,新进程通常会根据可执行文件所有者获得有效用户 ID。对于 root 拥有的程序,这可以提供 root 获准的访问,但只在程序运行期间有效,而且仅限代码执行的操作。
这种机制可以让经过谨慎编写的程序验证请求,再对受保护状态进行受限更改。例如,本地密码更改工具可能需要受控访问普通用户无法直接编辑的认证数据。现代实现还依赖 PAM、文件锁、策略和其他保护措施;仅凭 setuid 无法解释完整工作流。
采用 setuid 可执行文件时,主要从文件所有者取得哪个身份?
设置和移除该位
使用符号形式设置 setuid:
$ sudo chmod u+s myfile
在八进制记法中,setuid 在开头的特殊位数字中贡献 4:
$ sudo chmod 4755 myfile
这里,开头的 4 设置 setuid,755 设置普通所有者、组和其他权限位。使用 chmod u-s myfile 可移除 setuid,而不改变其他模式位。
哪个开头的八进制值表示 setuid 特殊位?
把 Setuid 视为安全敏感机制
特权 setuid 程序中的缺陷可能成为权限提升路径。这类程序必须验证输入、控制其信任的环境和文件路径、避免不安全的子进程行为、尽量减少特权代码,并尽早放弃提升后的凭据。
Linux 通常不会在解释型脚本上采用 setuid,因为安全实现会遇到竞态和解释器相关问题。使用 nosuid 挂载的文件系统也会抑制 setuid 和 setgid 效果。需求合适时,应优先选择由服务中介的操作、范围严格的 sudo 策略或 capabilities 等更窄的机制。
绝不要为了在共享系统上试验,就给任意 shell、解释器或复制的程序添加 setuid。应审计现有 setuid 文件,并只在隔离的可丢弃环境中练习。
使用 nosuid 挂载文件系统有什么作用?
课程已完成
你已完成 Setuid
现在,你可以识别 setuid,并说明它对凭据和安全性的影响。
在所有者执行位置查找
s或S。把 setuid 执行与可执行文件所有者的有效用户身份联系起来。
使用符号或八进制
chmod模式设置或移除该位。把每个特权可执行文件都视为安全敏感代码。