Linux系统中UID 0账户不止root,需立即排查所有UID 0用户:执行awk -F: '$3==0{print $1":"$3":"$6":"$7}' /etc/passwd筛选,确认是否为合法应急账户、工具误配或攻击者植入;警惕useradd -o绕过校验;检查空密码($2=="")及异常UID 0进程。

UID 0 账户不止 root?立刻查清所有特权用户
Linux 系统中 UID 0 拥有等同于 root 的全部权限,但 /etc/passwd 里可以存在多个 UID 0 的账户——这不是 bug,是 POSIX 允许的行为。一旦出现非 root 的 UID 0 用户(比如 admin、backup 或拼写错误的 rrot),极大概率是后门或配置失误。
执行这条命令快速筛出所有 UID 0 账户:
awk -F: '$3 == 0 {print $1 ":" $3 ":" $6 ":" $7}' /etc/passwd正常情况只应输出类似 root:0:/root:/bin/bash。若有多行,每一行都需人工确认来源:
– 是运维手动添加的应急账户?
– 是某自动化工具(如 Ansible playbook、Puppet 模块)误配?
– 还是攻击者通过 useradd -u 0 -o 植入的隐蔽账户?
警惕 useradd -o 的绕过行为
useradd -o 参数允许创建重复 UID 的用户,它不校验唯一性,也不报错,是排查中最容易被忽略的入口点。很多安全扫描工具默认不告警此操作,但系统日志里其实留痕。
- 检查命令历史:
history | grep "useradd.*-o" - 查看认证日志中可疑新增:
lastlog | awk '$3 != "Never" && $1 !~ /^(root|sync|shutdown|halt)$/ {print $1}' | head -10 - 比对
/etc/shadow中密码字段:UID 0 非 root 账户若密码哈希为空(::)或为已知弱哈希(如$1$开头旧 MD5),风险极高
systemd 环境下隐藏 UID 0 进程更难发现
传统 ps aux | grep root 会漏掉以 UID 0 运行但用户名非 root 的进程——因为 ps 默认显示的是 /proc/[pid]/status 中的 Uid: 字段,而用户名来自 /etc/passwd 映射。若该 UID 在 passwd 中对应的是伪装账户,ps 仍会显示那个名字,造成误判。
更可靠的方式是直接读取 UID 数值:
ps -eo uid,comm,args | awk '$1 == 0 && $2 != "systemd" && $2 != "kthreadd" {print}'注意:
– systemd 和 kthreadd 是内核线程,UID 0 属正常
– 若看到 bash、nc、python3、sshd 等用户态进程 UID 为 0,且不属于 root 用户启动的会话,基本可判定异常
– 这类进程常驻在后台、父 PID 为 1,且无对应 tty,用 lsof -nP -p [PID] 查其打开的网络端口和文件
/etc/passwd 第二字段(密码占位符)为空 ≠ 无密码
/etc/passwd 第二字段是密码占位符,现代系统通常为 x 或 *,表示密码存于 /etc/shadow。但若此处是空(::),代表该账户**无需密码即可登录**——这对 UID 0 账户是灾难性的。
检查方式:
awk -F: '$3 == 0 && $2 == "" {print $1}' /etc/passwd这种账户可通过 su - <username> 或 SSH(若 PermitEmptyPasswords yes)直接提权,且不会在 /var/log/auth.log 中留下密码失败记录。修复不是简单删掉账户,而是先确认是否被用于合法服务(比如某些嵌入式 init 脚本),再决定禁用(usermod -L)、锁定(passwd -l)或彻底删除(userdel)。
真实环境中,UID 0 多账户往往藏在批量脚本、容器镜像构建层、或 CI/CD 流水线的临时用户创建步骤里;人工肉眼扫 /etc/passwd 不够,得把检查逻辑固化进主机配置审计流程里。










