Linux中UID为0账户必须唯一,多出的UID 0用户极可能是后门或误配,需通过awk筛/etc/passwd、联动/etc/shadow查空密码弱哈希、用ps -eo按UID数值查隐藏进程,并交叉验证proc与内核模块。

Linux系统中UID为0的账户不只root一个,多个UID 0用户意味着特权账户失控,必须立即排查。关键不是“有没有重复”,而是“有没有非预期的UID 0账户”——它极可能是后门、误配或攻击痕迹。
快速筛出所有UID 0账户
执行以下命令,直读/etc/passwd:
awk -F: '$3 == 0 {print $1 ":" $3 ":" $6 ":" $7}' /etc/passwd
正常输出应仅有一行:root:0:/root:/bin/bash。若出现多行(如admin:0:/home/admin:/bin/bash、backup:0:/tmp:/sbin/nologin),每一行都需人工溯源:
- 是否为运维临时创建的应急账户?有无审批记录和到期机制?
- 是否由Ansible、SaltStack等自动化工具误配(例如playbook中漏写
uid校验)? - 是否通过
useradd -u 0 -o强行添加?-o参数绕过UID唯一性检查,日志中可能仅留useradd: warning: UID 0 is not unique,极易被忽略。
验证账户合法性:密码、时间与行为
仅看/etc/passwd不够,要联动/etc/shadow和系统日志:
- 查空密码:awk -F: '$3 == 0 && $2 == "" {print $1}' /etc/shadow —— UID 0 + 空密码字段(
::)属高危信号 - 查弱哈希:awk -F: '$3 == 0 && $2 ~ /^\$1\$/ {print $1}' /etc/shadow —— MD5旧哈希易被离线破解
- 查新增时间:ls -l /etc/passwd 看修改时间是否异常;再用 lastlog | awk '$3 != "Never" && $1 !~ /^(root|sync|halt|shutdown)$/ {print $1, $3}' 找非系统账户的最近登录时间
揪出UID 0的隐藏进程
传统ps aux | grep root会失效——因为进程用户名来自/etc/passwd映射,而攻击者可让UID 0进程显示为任意名字(如sshd或systemd-journal)。可靠做法是直接按UID数值筛选:
ps -eo uid,comm,args | awk '$1 == 0 && $2 !~ /^(systemd|kthreadd|migration|rcu)/ {print}'
重点关注输出中含以下关键词的进程:
-
bash、sh、python3、nc、curl—— 非系统启动的交互式或网络工具 - 父PID不是1或2,且无TTY(
ps -o pid,tty,comm -u $(whoami)对比) - 用
lsof -nP -p [PID]查其打开的端口和文件,若监听公网端口或连接可疑IP,基本确认为后门
交叉验证防绕过:proc、模块与命令一致性
高级后门常劫持ps、ls等命令输出。需绕过用户态钩子,从内核接口比对:
- 查真实进程路径:for pid in /proc/[0-9]*; do [ -f "$pid/exe" ] && echo "$pid: $(readlink $pid/exe 2>/dev/null)"; done | grep -v '(deleted)' —— 出现
(deleted)或指向/tmp、/dev/shm的,高度可疑 - 查异常内核模块:lsmod | awk '$3 > 100000 || $4 !~ /^[a-zA-Z0-9_,]+$/ {print}' —— 体积过大、作者字段为空或含乱码的模块需重点审查
- 多工具PID比对:comm -3 —— 若
/proc目录下有PID未出现在ps输出中,说明进程被隐藏

















