直接检查 /etc/pam.d/sshd 中是否存在非预期的 pam_tally2 或 pam_listfile 调用,重点关注 auth/account 栈中带 onerr=succeed、silent、[default=ignore] 等隐蔽参数的行,以及指向临时目录或非常规路径的配置。

怎么看 pam.d/sshd 里有没有被塞进可疑的 pam_tally2 或 pam_listfile
直接查文件内容,别信“默认没改”——攻击者常把后门模块加在 auth 或 account 栈里,位置靠前、不报错、还能绕过密码策略。重点不是“有没有这俩模块”,而是“有没有非预期的调用”。
- 执行
grep -E '^(auth|account).*pam_(tally2|listfile)' /etc/pam.d/sshd,看输出是否包含你没手动配过的行 - 特别注意
[default=ignore]、silent、onerr=succeed这类参数,它们会让失败不暴露、日志不记录 -
pam_tally2在较新系统(RHEL 8+/Ubuntu 20.04+)已被pam_faillock取代,如果看到它出现在新系统sshd配置里,大概率是异常 - 检查路径:有些后门会用绝对路径加载恶意 so,比如
/lib/security/./pam_tally2.so(利用点号绕过简单字符串匹配)
pam_listfile 怎么被用来做权限后门
它本意是限制用户登录(比如只允许某个组),但攻击者会反向利用:指定一个攻击者可控的文件(如 /tmp/allow.list),再设成 onerr=succeed,这样只要文件不存在或读取失败,就直接放行——而文件权限往往被设为仅属主可写,运维根本看不到内容变动。
- 典型后门写法:
auth [default=ok] pam_listfile.so item=user sense=allow file=/var/tmp/.logins onerr=succeed - 关键破绽:正常业务极少在
auth栈用pam_listfile,更不会指向临时目录下的隐藏文件 - 验证方法:运行
ls -l /var/tmp/.logins,如果存在且属主是普通用户(非 root),立刻检查内容;如果不存在,onerr=succeed就让它成了永远通过的开关
pam_tally2 的 silent 模式怎么躲过登录失败统计
攻击者加 silent 参数不是为了省日志,是为了让 pam_tally2 完全不触发计数逻辑——哪怕你输错十次密码,它也不拦、不记、不写日志,等于把账户锁机制整个拆掉。
- 检查命令:
grep 'pam_tally2.*silent' /etc/pam.d/sshd - 真实案例中,这一行常和
deny=0搭配出现,表面是“不限制失败次数”,实则是让模块彻底失效 - 注意
pam_tally2 --user xxx查出来的计数可能是假象——如果配置里带silent,实际认证过程根本没走计数分支 - RHEL/CentOS 7 之后建议用
pam_faillock替代,它的fail_interval和unlock_time更可控,且不支持 silent 这种危险参数
为什么光看 pam.d/sshd 不够,还得查 PAM 加载链
模块可以被其他 PAM 文件间接引入,比如 common-auth 被 sshd include,而攻击者可能只动那一层——你以为没改 sshd,其实它早就通过 @include common-auth 把后门带进来了。
- 执行
grep -r 'pam_(tally2|listfile)' /etc/pam.d/ --include="*auth*" 2>/dev/null,覆盖所有 auth 类配置 - 检查
sshd文件顶部是否有@include行,顺着它一层层追下去,直到找到实际定义模块的地方 - 注意 systemd 系统可能启用
PAMStack,部分模块由/usr/lib/pam.d/system-auth统一控制,改这里影响面更大 - 最稳妥的验证方式:用
sshd -T | grep -i pam看运行时实际加载的模块顺序(需 sshd 未运行或用测试模式)
真正难搞的不是某一行配置,是模块参数和上下文的组合效果——onerr=succeed 单看无害,配上 file=/dev/shm/.cfg 就成了后门;silent 单独出现像优化,嵌在 auth [success=done default=ignore] 里就是逻辑跳转陷阱。盯住参数意图,比盯住模块名重要得多。










