快速识别/etc/pam.d/sshd中的未知模块:检查非默认.so路径或陌生模块名,对比系统包管理器验证来源,警惕路径伪装;加载失败日志不等于后门,真正危险的是静默加载并异常行为的模块;需结合auditd监控运行时加载、动态认证测试及全量PAM文件排查。

如何快速识别 /etc/pam.d/sshd 中的未知模块
直接看文件里有没有非系统默认的 .so 文件路径或陌生模块名。Ubuntu/Debian 默认只用 pam_permit.so、pam_deny.so、pam_env.so 等少数几个;RHEL/CentOS 常见的是 pam_unix.so、pam_succeed_if.so、pam_faildelay.so。一旦出现像 pam_backdoor.so、libhijack.so 或指向 /tmp/、/dev/shm/ 的路径,基本可判定异常。
- 用
grep -E '^\s*[a-z]+\s+[a-z]+\s+/[^[:space:]]+\.so' /etc/pam.d/sshd提取所有显式加载的 .so 模块路径 - 对比系统包管理器记录:Debian/Ubuntu 执行
dpkg -S $(basename /path/to/module.so) 2>/dev/null;RHEL/CentOS 用rpm -qf /path/to/module.so - 注意伪装成合法模块名但路径异常的情况,例如
pam_env.so后面跟了\/tmp\/pam_env.so—— 这是典型绕过检测的手法
为什么 unknown module 错误日志不一定代表后门
sshd 启动时若加载失败,会在 journalctl -u sshd 或 /var/log/auth.log 中报类似 PAM unable to dlopen(/path/to/unknown.so): /path/to/unknown.so: cannot open shared object file,但这只是说明模块不存在或权限不对,并不等于已被执行。真正的后门往往静默加载成功,不报错,只在认证流程中触发恶意逻辑。
- 真正危险的是“加载成功但行为异常”的模块:比如在
auth [default=ignore]行里插入一个不报错、不拦截、却偷偷把密码写入/dev/shm/.log的模块 - 检查模块是否被实际调用:临时注释可疑行,重启
sshd,再用ssh -o PubkeyAuthentication=no user@host触发密码认证,观察strace -e trace=openat,open,connect -p $(pgrep -n sshd)是否打开非常规路径 - 有些后门会 hook
pam_authenticate()或pam_acct_mgmt(),仅靠静态分析不够,需结合动态行为监控
用 auditd 监控 PAM 模块加载行为
Linux 内核对 dlopen() 调用本身不审计,但可以监控 sshd 进程对 .so 文件的 openat 和 mmap 操作,这是最接近 runtime 的检测方式。
- 加规则:
auditctl -w /etc/pam.d/sshd -p wa -k pam_config(监控配置变更) - 再加:
auditctl -a always,exit -F path=/lib/x86_64-linux-gnu/security/ -F perm=x -k pam_module_load(Debian/Ubuntu 路径,RHEL 改为/lib64/security/) - 查日志:
ausearch -k pam_module_load | grep -E '(sshd|openat|mmap)' | awk '{print $13}' | sort -u—— 输出所有被sshd实际加载的模块绝对路径 - 注意:如果模块从非标准路径加载(如
/opt/malware/pam_x.so),这条规则不会捕获,需额外加-F path=/并过滤.so,但会产生大量噪音
修复后必须验证的三个点
删掉可疑行只是第一步。PAM 配置语法敏感,改错会导致 SSH 登录完全失效,且某些后门会写入其他 PAM 文件(如 /etc/pam.d/common-auth)做冗余备份。
- 运行
sshd -t只能验证语法,不能验证模块是否存在或是否被调用;必须用真实用户走一遍密码登录流程 - 检查所有关联文件:
grep -l 'pam_.*\.so' /etc/pam.d/{sshd,common-auth,system-auth,auth},避免漏掉横向植入 - 确认模块文件本身已删除:不是只删配置行,还要
find / -name '*backdoor*.so' 2>/dev/null并校验md5sum,因为有些后门会把模块藏在/usr/lib64/ld-linux-x86-64.so.2这类名字下
最麻烦的是那些不落地、从内存加载的模块——它们根本不在磁盘上,只靠配置里一行 auth [success=ok default=ignore] /dev/stdin 配合恶意 SSH banner 协议交互实现。这种得靠网络流量和进程内存 dump 追踪,普通配置扫描无能为力。










