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

作者:小白安全成长记 发布:2026-11-06 11:27 收录:2026-11-10 12:10 2 次阅读 约 2652 字
摘要:漏洞预警|ssh曝密码绕过漏洞CVE-2026-123158,输入300个a可以直接登录的那种,附漏洞排查脚本和利用poc
推荐理由:本文涵盖「SSH」、「CVE」、「POC」等多个主题,重点关注 SSH。

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

转载声明:本文转载自原发布平台 (作者:小白安全成长记), 原文标题《漏洞预警|ssh曝密码绕过漏洞CVE-2026-123158,输入300个a可以直接登录的那种,附漏洞排查脚本和利用poc》, 查看原文。 版权归原作者及原发布平台所有,本站仅作收录与展示,未对正文内容作实质性修改; 若涉及侵权请联系本站处理。