CentOS停止官方维护后,大量存量的服务器依然在运行。这些系统上最容易出现的问题之一,就是随着时间推移,运维人员轮换、业务系统更迭,留下了许多无人知晓的弱口令账号。这些账号就像埋在地基下的空洞,平时看不见,一旦被攻击者扫描出来,整个内网就可能被横向打穿。排查这类残留账号,不能只靠肉眼去/etc/passwd里翻,必须有一套可批量、可验证、可追溯的操作流程。
第一步:拉出全量账号清单,区分系统账号与业务账号排查的第一步不是直接跑破解工具,而是先搞清楚系统里到底有哪些账号。很多人习惯直接cat /etc/passwd,但这会混杂大量系统内置账号,比如daemon、bin、sys等,这些账号通常没有登录shell,也禁用了密码。我们需要把真正具备登录能力的账号筛出来。执行以下命令,可以列出所有可登录的账号:
cat /etc/passwd | grep -v '/sbin/nologin' | grep -v '/bin/false'
这条命令会过滤掉那些shell为/sbin/nologin或/bin/false的账号。输出结果里,UID在1000以上的通常是业务或运维人员创建的账号,但也不绝对,有些老系统可能把业务账号UID设得很低。所以还需要结合/etc/shadow文件,看看哪些账号存在密码哈希值。如果某个账号在/etc/shadow里显示为“!!”或“*”,说明密码被锁定,这类账号可以暂时放一放,优先排查那些有真实密码哈希的账号。
第二步:批量提取弱口令特征,利用John the Ripper进行离线碰撞拿到可疑账号列表后,不能直接去线上暴力破解,那会触发登录失败锁定策略,甚至把生产服务打挂。正确的做法是把/etc/passwd和/etc/shadow合并成一个John可识别的文件,拉到离线环境去跑。合并命令很简单:
unshadow /etc/passwd /etc/shadow > /tmp/hashes.txt
接下来用John the Ripper加载一份精简的弱口令字典。这份字典不需要太大,但一定要覆盖常见的高危弱口令模式,比如“123456”“password”“qwerty”,以及账号名本身、账号名加年份、账号名加数字后缀等组合。很多运维习惯给临时账号设一个和账号名相同的密码,或者“test123”“admin2023”这类,这些才是残留账号的重灾区。跑John的时候可以指定规则模式:
john --wordlist=/path/to/weakpass.txt --rules /tmp/hashes.txt
跑出来的结果要逐一记录。这里有个容易被忽视的细节:如果某个账号的密码被John秒破,但该账号在业务上已经不再使用,说明这是一个典型的残留弱口令账号,必须立即处理。如果账号还在使用,那问题就更严重了,说明运维侧存在长期未整改的弱口令策略。
第三步:排查无密码或空密码账号CentOS系统里,如果某个账号在/etc/shadow中的密码字段为空,或者仅包含一个感叹号但实际允许空密码登录,这比弱口令更危险。检查空密码账号可以用以下命令:
awk -F: '($2 == "" || $2 == "!") {print $1}' /etc/shadow
这条命令会列出所有密码字段为空或仅有一个感叹号的账号。但要注意,有些系统账号的密码字段是“!!”,这表示密码被锁定,无法登录。真正危险的是那些密码字段完全为空的行。如果发现这样的账号,要立刻确认该账号是否属于业务需要。绝大多数情况下,空密码账号都应该被锁定或删除。锁定账号的命令是:
passwd -l 用户名
锁定后,该账号的密码字段会被加上两个感叹号前缀,彻底禁止密码登录。
第四步:检查SSH密钥登录残留弱口令排查不能只看密码,很多残留账号是通过SSH密钥对实现免密登录的。攻击者一旦拿到某个弱口令账号的shell,第一件事就是往~/.ssh/authorized_keys里写入自己的公钥,以此建立持久化后门。排查时,要遍历所有可登录账号的家目录,检查authorized_keys文件是否存在,以及文件里是否有不明来源的公钥。可以写一个简单的批量脚本:
for user in $(cat /etc/passwd | grep -v '/sbin/nologin' | grep -v '/bin/false' | cut -d: -f1); do
home_dir=$(eval echo ~$user)
if [ -f "$home_dir/.ssh/authorized_keys" ]; then
echo "检查用户: $user"
cat "$home_dir/.ssh/authorized_keys"
fi
done
输出结果需要人工审核。如果发现某个公钥的注释信息与当前运维团队无关,或者公钥指纹在内部资产库中查不到,就要高度警惕。这类残留密钥往往是前员工留下的,或者攻击者植入的。清理时不能只删文件,还要检查该账号最近的登录日志,确认是否有异常登录行为。
第五步:利用last和lastb追溯账号活动轨迹排查出弱口令账号后,不能一删了之。必须先搞清楚这些账号最近有没有被登录过,从哪里登录的。last命令可以查看成功登录记录,lastb可以查看失败登录记录。针对每个可疑账号,执行:
last 用户名
和
lastb 用户名
重点关注登录来源IP。如果发现来自非业务网段、境外IP或者完全陌生的地址,说明该账号可能已经被入侵利用。此时需要立即隔离服务器,提取登录日志、历史命令记录和进程列表,进行应急响应。即使没有异常登录记录,也不能掉以轻心,因为攻击者可能已经清理了日志。这时可以结合/var/log/secure或/var/log/auth.log里的sshd日志,搜索该账号的认证记录,交叉验证。
第六步:批量整改与加固策略排查出问题账号后,整改要分优先级。对于确认不再使用的残留账号,直接删除:
userdel -r 用户名
加-r参数会同时删除该账号的家目录和邮件目录,避免残留文件。对于仍需使用但存在弱口令的账号,强制用户下次登录修改密码,并设置密码复杂度策略。在CentOS上,可以通过/etc/pam.d/system-auth配置密码最小长度、字符类型要求。例如,在pam_pwquality.so行增加参数:
password requisite pam_pwquality.so try_first_pass local_users_only retry=3 minlen=12 dcredit=-1 ucredit=-1 ocredit=-1 lcredit=-1
这条配置要求密码至少12位,包含数字、大写字母、小写字母和特殊字符。同时,在/etc/login.defs中设置密码最大使用天数和过期警告天数,防止弱口令长期不变。
第七步:建立定期自动化排查机制一次性排查只能解决存量问题,增量风险要靠自动化机制来兜底。可以写一个简单的shell脚本,每周通过cron执行一次,自动检查空密码账号、新增的可登录账号、authorized_keys变动情况,并将结果发送到运维邮箱。脚本的核心逻辑可以这样组织:
#!/bin/bash
report="/tmp/account_check_$(date +%F).txt"
echo "空密码账号检查:" > $report
awk -F: '($2 == "" || $2 == "!") {print $1}' /etc/shadow >> $report
echo "新增可登录账号:" >> $report
diff /root/old_passwd /etc/passwd | grep "^>" | grep -v '/sbin/nologin' >> $report
# 更新基准文件
cp /etc/passwd /root/old_passwd
# 发送报告
mail -s "账号安全周报" ops@example.com < $report
这个脚本每次运行时会对比当前/etc/passwd与上一次快照的差异,发现新增的可登录账号就告警。虽然简陋,但能有效弥补人工排查的滞后性。对于规模较大的环境,建议引入Osquery或者自研的资产巡检平台,把账号、密码策略、SSH密钥等信息统一采集到后端做聚合分析。
容易被忽略的两个死角第一个死角是容器环境。很多CentOS服务器上运行着Docker,容器内部的账号体系独立于宿主机。如果容器镜像里内置了弱口令账号,宿主机的排查完全覆盖不到。需要对运行中的容器执行同样的账号检查,或者直接在镜像构建阶段就加入安全扫描。第二个死角是数据库账号。MySQL、PostgreSQL等数据库内部也可能存在弱口令残留账号,这些账号不会出现在/etc/passwd里,需要登录数据库执行user表查询。很多攻击者拿到服务器权限后,会故意在数据库里创建隐藏账号,作为二次进入的后门。
排查CentOS残留弱口令账号,本质上是一次对系统身份资产的全面盘点。这个过程会发现很多历史遗留问题:离职员工的账号没清理、临时测试账号忘了删、业务割接时创建的同步账号密码万年不变。这些问题平时不影响业务运行,但一旦被利用,后果就是整个内网的沦陷。把排查流程固化下来,变成运维的常规动作,远比事后救火更有价值。
