上一篇你学会了 rwx 基础权限和 chmod/chown 操作。现在思考一个实际问题:普通用户 kali 执行 passwd 修改密码时,需要写入 /etc/shadow 文件——但这个文件的权限是 -rw-r----- root shadow,普通用户既不是所有者也不在 shadow 组。kali 是怎么改密码的?
答案就是 SUID——Linux 三种特殊权限位之一。传统 rwx 只能控制「谁能读写执行」,而特殊权限位能控制「以谁的身份执行」。这在安全领域至关重要:SUID 配置错误是 Linux 提权漏洞最常见的入口之一,后续模块4「漏洞利用与后渗透」中的 SUID 提权技术正是建立在本篇知识之上。
SUID(Set User ID)机制就像政务大厅的服务窗口。你去办护照时,提交申请的是你本人(执行者),但盖章生效用的是工作人员的职权(文件所有者的权限)。passwd 命令就是这个窗口——你以 kali 身份运行它,但它写入 /etc/shadow 时用的是 root 的权限。
查看 passwd 命令的权限,注意所有者执行位上的字母:
权限字符串 -rwsr-xr-x 中,所有者执行位不是 x 而是 s——这就是 SUID 标志。它表示「无论谁执行这个程序,进程都将以文件所有者(root)的身份运行」。
S 表示所有者本身没有执行权限,SUID 形同虚设——程序都无法执行,身份切换更无从谈起。必须先确保有 x 权限,小写 s 才有效。修复:chmod 4755 而非 chmod 4644。SGID(Set Group ID)作用于目录时,像公司部门的共享文件柜——放进去的文件自动盖上部门章(继承目录的所属组),这样部门所有人都能按组权限访问,不需要逐个文件修改 chown。
SGID 对文件和目录的效果不同:
2770 中第一位 2 就是 SGID。验证效果——在共享目录中创建文件,观察所属组是否自动继承:
文件所有者是 kali,但所属组是 devteam 而非 kali 的默认组——这就是 SGID 的效果。devteam 组的所有成员都能按组权限(rwx)访问这个文件,无需额外配置。
Sticky Bit 像公共储物柜——所有人都能往柜子里放东西(目录有写权限),但只有自己存的东西才能取走(删除),别人的格子碰不了。Linux 中最典型的例子是 /tmp 目录。
权限字符串 drwxrwxrwt 末尾的 t 就是 Sticky Bit 标志。/tmp 权限是 1777(所有人可读写执行),但没有 Sticky Bit 的话,任何用户都能删除别人创建的临时文件——这在多用户系统中是灾难性的。
| 权限 | 数字前缀 | 符号法 | 对文件效果 | 对目录效果 |
|---|---|---|---|---|
| SUID | 4 | u+s |
以所有者身份执行 | 通常无意义 |
| SGID | 2 | g+s |
以所属组身份执行 | 新文件继承目录的组 |
| Sticky | 1 | +t |
现代系统已废弃 | 仅文件所有者可删除 |
三位特殊权限可以组合使用。例如 chmod 3770 表示同时设置 SGID(2)+ Sticky Bit(1)= 3,再加 770 基础权限。上一篇的开放挑战题正是需要 SGID + Sticky Bit 组合。
SUID 是双刃剑——系统需要它正常运作(passwd、sudo),但攻击者一旦找到配置不当的 SUID 程序,就能直接提权到 root。渗透测试中,进入目标系统后的第一步就是枚举 SUID 文件。使用 find 命令可以快速搜索:
-perm -4000 表示匹配权限中包含 SUID 位(4)的文件。2>/dev/null 将权限不足导致的错误信息丢弃,保持输出干净。安全审计时,重点关注非标准路径下的 SUID 文件:
Kali 系统上常见的 SUID 程序及其安全状态:
| 程序路径 | 状态 | 说明 |
|---|---|---|
/usr/bin/passwd |
正常 | 修改密码需写 /etc/shadow |
/usr/bin/sudo |
正常 | 提权执行命令的核心程序 |
/usr/bin/pkexec |
需关注 | PolicyKit,历史漏洞多(CVE-2021-4034) |
/usr/bin/vim |
高危 | 若有SUID,可用 :!sh 获取root shell |
/usr/bin/find |
高危 | 若有SUID,可用 -exec 执行任意命令 |
自定义SUID脚本 |
高危 | Shell脚本设SUID无效,但二进制脚本极易提权 |
find . -exec /bin/sh \; 即可获取 root shell。这个知识点将在模块4深入展开。传统 rwx 权限有个硬伤:每个文件只能有一个所有者和一个组,无法对「特定用户」单独授权。例如你想让用户 guest 读取某个文件,但不想把 guest 加入文件所属组——传统权限做不到。ACL(Access Control List)解决了这个问题,它允许你为任意单个用户或组设置独立权限,不受 u/g/o 三组限制。
-m 表示 modify(添加/修改),-x 表示 remove(移除)。格式为 u:用户名:权限 或 g:组名:权限。设置后用 getfacl 查看完整 ACL:
user:guest:r-x 就是 ACL 添加的独立条目——guest 用户有读和执行权限,但不影响其他用户的权限。mask::rwx 是 ACL 掩码,限制 ACL 条目的最大权限上限——即使给 guest 设了 rwx,如果 mask 是 r-x,guest 实际只有 r-x。
ls -l 的权限字符串末尾会多出一个 + 号(如 drwxrwxr-x+),这是快速判断文件是否配置了 ACL 的方法——不需要每次都跑 getfacl。ls -l /usr/bin/passwd /usr/bin/sudo /usr/bin/su,找到每个文件权限字符串中的 SUID 标志(小写 s),解释为什么这三个程序需要 SUID 权限。/opt/audit,要求:devteam 组成员可创建文件(读写执行),audit 组成员只能读取(不可写不可执行),所有人创建的文件只有自己能删除。提示:组合使用 SGID + Sticky Bit + ACL 三种机制。chmod 3770 设置 SGID+Sticky,再用 setfacl -m g:audit:r 给 audit 组单独读权限。find、vim、python3 三个程序的 SUID 提权方法。思考:为什么 Linux 系统默认不给这些常用程序设置 SUID?这将在模块4「漏洞利用与后渗透」中深入探讨。