漏洞预警|ssh曝密码绕过漏洞CVE-2026-123158,输入300个a可以直接登录的那种,附漏洞排查脚本和利用poc"

admin 2026-11-09 01:42:46 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

漏洞预警|ssh曝密码绕过漏洞CVE-2026-123158,输入300个a可以直接登录的那种,附漏洞排查脚本和利用poc

原创

小白哥
小白哥

小白安全成长记

2026年11月6日 11:29
河北

去阅读

SSHhole(CVE-2026-123158)漏洞分析、利用条件与排查指南

又出洞了,还能密码绕过,还是ssh,要开始口吐芬芳了。估计运维老表们这周又是加班的一周了,我也赶忙搞了一下,还好,我用的不多,哈哈哈哈哈。但是排查脚本还是得安排一下,主要还是alpine 和 openwrt,大家还是查查,给运维老表个交代吧。

一、漏洞概述

SSHhole(CVE-2026-123158)是一个影响 OpenSSH SSH 密码认证过程的安全漏洞。漏洞主要涉及使用 musl libc 的 Linux 系统,在特定认证配置下,攻击者可能通过提交特殊构造的超长密码,绕过 SSH 密码认证,登录原本不允许密码登录的账户。漏洞的核心问题是:musl libc 在处理超长密码时,crypt() 函数可能返回 *,而 OpenSSH 在特定认证逻辑中可能将该返回值与 /etc/shadow 中的密码字段进行比较,从而导致错误匹配。

▍漏洞基本信息

项目 内容
漏洞名称 SSHhole
CVE 编号 CVE-2026-123158
影响组件 OpenSSH 7.3p1 至 10.6p1
CVSS评分 8.1
关联组件 musl libc
漏洞类型 SSH 密码认证绕过
主要影响环境 musl libc + 未启用 PAM 的 Linux
利用方式 特定条件下通过超长密码触发认证绕过
修复版本 OpenSSH 10.6p2
典型影响系统 Alpine Linux、部分 OpenWrt、Buildroot、Yocto 环境

二、漏洞原理

▍2.1 正常 SSH 密码认证流程

Linux 系统通常通过 /etc/shadow 保存用户密码哈希。

例如:

root:*
alpine:*
admin:$6$xxxxxxxx$xxxxxxxxxxxxxxxx

其中:

  • root:*:表示该账户没有可用的常规 Unix 密码认证凭据。
  • alpine:*:同样属于密码字段为 * 的账户。
  • admin:$6$...:表示该账户使用 SHA-512 格式的密码哈希。

在未启用 PAM 的特定 OpenSSH 认证路径中,OpenSSH 会调用系统的 crypt() 函数处理用户输入的密码,并将结果与账户密码哈希进行比较。

▍2.2 漏洞产生的原因

问题出现在 musl libc 对超长密码的处理过程中。

当攻击者提交超过特定长度限制的密码时,crypt() 可能返回特殊值 *,而不是正常的密码哈希。

如果目标账户的 /etc/shadow 密码字段也为 *,就可能出现错误匹配。

正常情况 异常情况
用户输入密码 用户提交超长密码
crypt() 生成密码哈希 crypt() 返回 *
比较密码哈希 比较特殊返回值
密码不匹配则认证失败 可能错误匹配 *
正常认证 可能绕过认证

三、漏洞利用的条件

SSHhole 并不是所有 Linux 系统都能利用,需要同时满足以下五个条件。

▍3.1 必要的条件

序号 条件 具体要求 排查重点
1 musl libc SSH 服务运行在 musl libc 环境 检查 sshd 动态链接库
2 PAM 未启用 SSH 使用非 PAM 密码认证路径 检查 UsePAM 和编译配置
3 开启密码认证 SSH 允许密码认证 PasswordAuthentication yes
4 存在目标账户 /etc/shadow 密码字段为 * 检查 shadow
5 存在 Donor Hash 存在有效的 $5$ 或 $6$ 密码哈希账户 检查 shadow

▍3.2 Donor Hash 是什么?(新知识点出现了,跟着我学更多新知识,哈哈哈哈哈)

Donor Hash 可以理解为提供有效密码哈希信息的账户。

在这个漏洞的认证逻辑中,目标账户密码字段为 *,而另一个具有有效 $5$ 或 $6$ 哈希的账户可能成为 Donor。

例如:

root:*
alpine:*
admin:$6$xxxxxxxx$xxxxxxxxxxxxxxxx

这里:

账户 密码字段 作用
root * 可能的目标账户
alpine * 可能的目标账户
admin $6$... 可能的 Donor 账户

需要注意:

  • Donor 账户需要满足有效账户状态要求。
  • 仅仅存在 $5$ 或 $6$ 字符串,并不能直接认定满足条件。
  • 账户锁定、过期、Shell 设置等也需要进一步核实。

▍3.3 哪些 Linux 系统需要重点排查?(windows 暂时不受影响)

Linux 系统 排查优先级 原因
Alpine Linux 高 常见 musl libc 环境
OpenWrt 高 部分固件使用 musl libc
Buildroot 高 嵌入式环境可能使用 musl
Yocto 高 取决于系统构建配置
Debian 一般 默认使用 glibc
Ubuntu 一般 默认使用 glibc
Fedora 一般 默认使用 glibc

注意:Debian、Ubuntu 等默认使用 glibc,并不意味着所有特殊构建环境都可以直接排除。并不是直接利用成功后就直接root权限了,取决于你用的哪个权限账号。

四、漏洞排查脚本(有必要安排一下)

下面提供一个 Shell 脚本,用于检查 Linux 系统是否满足 SSHhole 的五项条件。脚本采用只读检查,不会尝试漏洞利用,也不会修改系统配置。

▍4.1 检查的内容包括:

检查项目 检查方式
操作系统 /etc/os-release
SSH 服务 查找 sshd
libc 类型 ldd 检查
PAM 状态 sshd -T
密码认证 sshd -T
Root 登录策略 sshd -T
目标账户 检查 /etc/shadow
Donor Hash 检查 $5$、$6$

▍4.2 完整脚本

保存为 sshhole_check.sh:

#!/bin/sh

# SSHhole CVE-2026-123158
# Read-only security detection script

echo \"==========================================\"
echo \" SSHhole Vulnerability Detection\"
echo \" CVE-2026-123158\"
echo \"==========================================\"

# 1. Operating System
echo
echo \"[1] Operating System\"

if [ -f /etc/os-release ]; then
    grep -E '^(NAME|ID|VERSION_ID)=' /etc/os-release
fi

# 2. Find sshd
echo
echo \"[2] SSHD Binary\"

SSHD=$(command -v sshd 2>/dev/null)

if [ -z \"$SSHD\" ]; then
    for f in /usr/sbin/sshd /sbin/sshd; do
        if [ -x \"$f\" ]; then
            SSHD=\"$f\"
            break
        fi
    done
fi

if [ -z \"$SSHD\" ]; then
    echo \"[INFO] sshd not found\"
    exit 0
fi

echo \"SSHD: $SSHD\"

# 3. Check libc
echo
echo \"[3] libc Detection\"

LIBC_INFO=$(ldd \"$SSHD\" 2>&1)

if echo \"$LIBC_INFO\" | grep -qi 'musl'; then
    echo \"[RISK] musl libc detected\"
    MUSL=1
else
    echo \"[INFO] musl libc not detected\"
    MUSL=0
fi

echo \"$LIBC_INFO\" | grep -Ei 'musl|libc\\.so' | head -5

# 4. Effective SSH configuration
echo
echo \"[4] SSHD Configuration\"

SSHD_CONFIG=$(\"$SSHD\" -T 2>/dev/null)

if [ -z \"$SSHD_CONFIG\" ]; then
    echo \"[WARN] Cannot read effective SSHD configuration\"
    exit 1
fi

USEPAM=$(echo \"$SSHD_CONFIG\" |
    awk '$1==\"usepam\"{print $2; exit}')

PASSWORD=$(echo \"$SSHD_CONFIG\" |
    awk '$1==\"passwordauthentication\"{print $2; exit}')

ROOTLOGIN=$(echo \"$SSHD_CONFIG\" |
    awk '$1==\"permitrootlogin\"{print $2; exit}')

echo \"UsePAM: ${USEPAM:-unknown}\"
echo \"PasswordAuthentication: ${PASSWORD:-unknown}\"
echo \"PermitRootLogin: ${ROOTLOGIN:-unknown}\"

if [ \"$USEPAM\" = \"no\" ] || [ -z \"$USEPAM\" ]; then
    echo \"[RISK] PAM disabled or unavailable\"
    PAM_OFF=1
else
    echo \"[INFO] PAM enabled\"
    PAM_OFF=0
fi

if [ \"$PASSWORD\" = \"yes\" ]; then
    echo \"[RISK] Password authentication enabled\"
    PASS_ON=1
else
    echo \"[INFO] Password authentication disabled\"
    PASS_ON=0
fi

# 5. Account inspection
echo
echo \"[5] Account Inspection\"

if [ \"$(id -u)\" -ne 0 ]; then
    echo \"[WARN] Please run as root\"
    exit 1
fi

if [ ! -r /etc/shadow ]; then
    echo \"[WARN] Cannot read /etc/shadow\"
    exit 1
fi

TARGETS=\"\"
DONORS=\"\"

while IFS=: read -r user hash rest; do

    shell=$(awk -F: -v u=\"$user\" \\
        '$1==u {print $7; exit}' /etc/passwd)

    case \"$shell\" in
        */nologin|*/false|\"\")
            continue
            ;;
    esac

    case \"$hash\" in
        '*')
            TARGETS=\"${TARGETS}${user} \"
            ;;
        \\$5\\$*|\\$6\\$*)
            DONORS=\"${DONORS}${user} \"
            ;;
    esac

done < /etc/shadow

if [ -n \"$TARGETS\" ]; then
    echo \"[RISK] Potential target accounts: $TARGETS\"
    TARGET_FOUND=1
else
    echo \"[INFO] No target accounts found\"
    TARGET_FOUND=0
fi

if [ -n \"$DONORS\" ]; then
    echo \"[RISK] Potential donor accounts: $DONORS\"
    DONOR_FOUND=1
else
    echo \"[INFO] No donor accounts found\"
    DONOR_FOUND=0
fi

# 6. Root login policy
echo
echo \"[6] Root SSH Policy\"

case \"$ROOTLOGIN\" in
    yes)
        echo \"[WARN] Root SSH login is permitted\"
        ;;
    prohibit-password|forced-commands-only|no)
        echo \"[INFO] Root password login restricted\"
        ;;
    *)
        echo \"[WARN] Unknown root login policy\"
        ;;
esac

# 7. Final assessment
echo
echo \"==========================================\"
echo \" Final Assessment\"
echo \"==========================================\"

if [ \"$MUSL\" -eq 1 ] &&
   [ \"$PAM_OFF\" -eq 1 ] &&
   [ \"$PASS_ON\" -eq 1 ] &&
   [ \"$TARGET_FOUND\" -eq 1 ] &&
   [ \"$DONOR_FOUND\" -eq 1 ]; then

    echo \"[CRITICAL] ALL FIVE CONDITIONS MATCH\"
    echo \"Potentially vulnerable to SSHhole!\"

else

    echo \"[INFO] Five-condition match not established\"

    echo \"musl=$MUSL\"
    echo \"pam_disabled=$PAM_OFF\"
    echo \"password_auth=$PASS_ON\"
    echo \"target_account=$TARGET_FOUND\"
    echo \"donor_account=$DONOR_FOUND\"

fi

echo
echo \"[NOTE] Configuration-based assessment only.\"
echo \"Verify patches, account status and running binary.\"
echo \"==========================================\"

▍4.3 脚本用法

chmod +x sshhole_check.sh

sudo ./sshhole_check.sh

Alpine Linux 也可以直接执行:

sh sshhole_check.sh

▍4.4 脚本的检查结果说明

检查结果 含义
musl=0 未发现 musl 环境
pam_disabled=0 PAM 已启用
password_auth=0 未开启密码认证
target_account=0 未发现符合条件的目标账户
donor_account=0 未发现符合条件的 Donor 账户
五项均为 1 高度疑似满足漏洞条件

注意啊: 该脚本属于初步配置检查,不等于漏洞利用验证。不等于漏洞利用验证。

五、入侵排查

如果服务器已经满足 SSHhole 的利用条件,还需要进一步判断是否曾经被利用。

最值得关注的现象是:

密码字段为 * 的账户,却出现了 SSH 密码认证成功的日志。

▍5.1 检查 SSH 登录日志

Alpine Linux:

grep \"Accepted password\" /var/log/messages

Debian / Ubuntu:

grep \"Accepted password\" /var/log/auth.log

使用 systemd 的系统:

journalctl -u sshd --since \"7 days ago\"

重点关注以下日志:

Accepted password for alpine from 192.0.2.100 port 12345 ssh2

▍5.2 检查异常账户

例如:

grep '^alpine:' /etc/shadow

如果返回:

alpine:*:20125:0:99999:7:::

同时 SSH 日志中出现:

Accepted password for alpine

则属于高度可疑行为,需要进一步排查确认。

▍5.3 检查异常权限提升

检查是否存在异常用户:

awk -F: '$3 >= 1000 {print $1,$3,$7}' /etc/passwd

检查 doas 配置:

cat /etc/doas.conf

检查 SSH 公钥是否被植入:

find /root /home -name authorized_keys -type f -ls

检查近期修改的系统文件:

find /etc /root /home -type f -mtime -7 -ls

▍5.4 入侵排查的重点

排查方向 重点检查内容
SSH 登录 异常来源 IP、登录时间、账户
账户安全 新增用户、异常修改密码
权限提升 sudo、doas、异常特权操作
SSH 持久化 authorized\_keys、sshd\_config
系统持久化 crontab、启动脚本、服务
命令执行 Shell 历史、系统审计日志
网络活动 异常外联、反向连接、监听端口

注意:Accepted password 本身不能单独证明 SSHhole 被利用,还需要结合账户密码字段、认证配置、登录来源和补丁状态进行关联分析。

六、漏洞修复建议

▍6.1 升级 OpenSSH

推荐优先升级到包含修复补丁的版本。

OpenSSH 官方修复版本:

OpenSSH 10.6p2

Alpine Linux 可以使用:

apk update
apk upgrade -U -a

升级后重启 SSH:

rc-service sshd restart

需要注意,发行版可能通过补丁回移修复漏洞,因此不应只根据版本号判断是否安全,应以发行版安全公告和软件包修复状态为准。

▍6.2 临时关闭密码认证

如果暂时无法升级,可以关闭 SSH 密码认证。

编辑配置文件:

vi /etc/ssh/sshd_config

设置:

PasswordAuthentication no

检查配置:

sshd -t

重启服务:

rc-service sshd restart

执行之前应确保 SSH 公钥认证正常,避免远程管理连接中断。


最后给搞安全的兄弟安排的一些资料,请大家自觉遵守网络安全法

漏洞验证的poc:

  • https://github.com/predkambrij/sshhole-repro

漏洞作者的分析:

  • https://sshhole.com/

ssh官方修复说明:

* https://github.com/openssh/openssh-portable/commit/4353fdc43ef646c43a8dda7025cc1a898caf1482

评论:0   参与:  0