UID 0 的含义
Linux 判定权限看的是 UID 而不是用户名:/etc/passwd 第三字段为 0 的账号就是超级用户,权限与 root 完全相同。后门账号的经典做法有两种,一是新建账号后把 UID 改成 0,二是直接复制 root 那一行、只改用户名。所以核查只认 UID 不认名字,叫 dbadmin、sysbackup 的账号同样可能是完全特权账号。
基本信息
| 加固项 | 非 root 账号不得拥有 UID 0 |
|---|---|
| 适用平台 | Linux(RHEL/CentOS/Debian/Ubuntu) |
| 风险等级 | 高 |
| 判定标准 | UID 0 账号列表只应包含 root 一行 |
| 检查位置 | /etc/passwd 第三字段;目录服务账号用 getent 兜底 |
典型使用场景
- 交付自查与等保核查:证明设备上不存在多余的超级用户账号
- 应急响应取首证:账号被悄悄添加后,UID 0 清单是最快能定位的一步
- 周期巡检:把 UID 0 清单纳入定期核查,与上次记录比对差异
- 存量清理:早期运维图省事复制的 root 账号往往还留在 passwd 里
- 变更后复核:任何账号操作之后重跑一次,确认没有引入新的 UID 0
核查命令
核查命令
awk -F: '($3 == 0) { print $1 }' /etc/passwd # 预期只有 root 一行
awk -F: '($3 == 0) { print $1, $3, $4, $7 }' /etc/passwd # 一并看 GID 与登录 shell
grep -E ':0:0:' /etc/passwd # 双 0 比对:UID 与 GID 都为 0
getent passwd 0 # 含 LDAP/SSSD 等目录服务账号
stat -c '%y %n' /etc/passwd /etc/shadow # 看修改时间,近期被改要追来源passwd 逐字段读法
| 字段 | 含义 | 判读要点 |
|---|---|---|
| 用户名 | 登录名,仅为显示与登录用 | 名字普通不代表权限普通,不能据此排除 |
| 口令占位 | x 表示哈希存放在 shadow 中 | 出现明文或空字段要单独核查口令状态 |
| UID | 用户标识,0 即超级用户 | 除 root 外出现 0 一律按高危登记 |
| GID | 主组标识,0 即 root 组 | 只改 GID 为 0 的变体同样可读写 root 组文件 |
| 描述字段 | 账号备注信息 | 后门账号常留空或填写随意,可作辅助线索 |
| 家目录 | 登录后的起始目录 | 指向不存在的路径或为 / 的账号要额外核实 |
| 登录 shell | 登录后使用的 shell | 为 bash 或 sh 说明可交互登录,风险等级再上调 |
处置:先锁定再评估
处置:先锁定再评估
# 不要一上来就删账号,删除会产生无属主文件,破坏现场
usermod -L -s /usr/sbin/nologin rogue0 # 锁定口令并禁用登录 shell
passwd -l rogue0 # 或单独锁定口令
awk -F: '($3 == 0) { print $1 }' /etc/passwd # 复核处置结果
# 确认是历史遗留且无人使用后,再走变更流程删除:
# userdel rogue0 之后执行 find / -nouser -print 补扫无属主文件处置前确认该账号是否被业务直接使用:userdel -r 会连家目录一起删除,普通 userdel 也会让该账号名下文件变成无属主。删除属于变更动作,不在核查环节顺手做;核查阶段只记录证据(账号名、UID、家目录、创建与修改时间)。
只查 /etc/passwd 会漏掉目录服务里的账号:LDAP 与 SSSD 环境的 UID 0 账号在本地文件里看不到,统一用 getent 兜底。容器与 chroot 环境有各自独立的 passwd,也要按各自文件单独核查。
常见后门特征
- 账号名模仿系统账号:如 r00t、root0、adm1n、support 这类容易被扫一眼放过的名字
- UID 为 0,但家目录指向根目录或不存在的路径
- 描述字段留空,而同类系统账号通常有明确说明
- 创建时间与 passwd 文件修改时间接近,说明是同一批操作产生的
- 出现在全新建的系统上,却不属于该发行版的默认账号清单
把核查做成制度
UID 0 清单只在受控时才有意义:把「UID 0 只允许 root」写成基线条款,纳入周期核查与变更审批,禁止任何人工把 UID 改成 0 的操作绕过流程。核查输出连同 passwd 与 shadow 的修改时间一起归档,形成可跨期比对的证据链,评审时才有说服力。