一个超长密码,为什么能绕过 SSH 登录? OpenSSH 紧急补丁背后的十年旧坑
原创
JacobWang
JacobWang
NowSec
2026年11月6日 11:23
陕西
去阅读
11 月 5 日,OpenSSH 临时发布了 Portable OpenSSH 10.6p2。
这不是一次正常版本更新。
OpenSSH 维护者 Damien Miller 在公告里用了相当明确的措辞:如果你管理的是使用 musl libc、没有启用 PAM 的 Linux 系统,比如常见的 Alpine Linux,那么应该立即关闭密码登录,或者暂时关闭 SSH 服务。
在满足特定条件的服务器上,攻击者不需要知道正确密码,也可能成功登录。
漏洞随后被分配编号 CVE-2026-123158。
但如果只看一句“OpenSSH 密码绕过”,很容易把影响范围理解错。
这不是所有 Linux 都中招,也不是所有 OpenSSH 服务器都能直接免密登录。
真正需要同时满足几组条件。
先说结论:Ubuntu、Debian 这类系统通常不受影响
OpenSSH 官方给出的影响边界很清楚。
漏洞主要影响:
Linux 系统使用 musl libc;
sshd 没有使用 PAM 处理密码认证;
PasswordAuthentication 仍然开启;
系统中存在某些没有设置密码、以特殊字段表示的账号。
Alpine Linux 是最典型的受影响平台,因为它默认使用 musl libc,而且标准 openssh-server 包不通过 PAM 做密码验证。
OpenWrt、Buildroot、Yocto 等使用 musl 的精简 Linux 环境,在特定配置下也需要检查。
但常见的 Ubuntu、Debian、RHEL、Rocky Linux、AlmaLinux 等 glibc 系统,并不属于这次漏洞的典型影响范围。
使用 PAM 做密码认证的系统同样不受这一攻击路径影响。
所以这不是“全网 Linux SSH 沦陷”,但对使用 Alpine 作为云主机、轻量服务器和基础镜像的环境来说,优先级依然很高。
最奇怪的地方:密码算失败以后,返回了一个“\*”
这次漏洞的原理并不复杂,甚至有点“巧合得离谱”。
Linux 传统密码认证会把用户输入的密码交给 crypt() 处理,然后把结果和 /etc/shadow 里的密码字段进行比较。
正常用户的密码字段通常是一串真正的密码 Hash。
但很多不允许使用密码登录、只允许密钥登录的账号,会在密码字段里放一个特殊标记:
\*
它的本意很简单:
这不是一个真正的密码 Hash,因此正常密码永远不应该匹配它。
偏偏 musl libc 还有另一个行为。
当 crypt() 遇到某些无法处理的输入时,它不会像部分实现那样返回空值,而可能返回一个错误字符串。
这个错误字符串,同样是:
\*
于是两个原本毫无关系的东西撞到了一起。
一边的“\”表示这个账号没有可用密码;另一边的“\”表示密码计算失败。
如果调用方最后只是简单比较两个字符串,事情就麻烦了。
错误结果和账号的特殊密码字段竟然变成了“相等”。
为什么偏偏是“超长密码”?
musl 对部分密码 Hash 算法设置了输入长度上限。
当密码长度超过其可接受范围以后,crypt() 不再进行正常计算,而是进入错误处理路径。
研究人员发现,在受影响的组合下,使用超过正常长度的密码输入,可以稳定触发这个错误结果。
于是攻击过程从逻辑上变成:
目标账号密码字段是 \;
超长密码让 musl 的 crypt() 失败;
错误结果同样返回 \**;
sshd 继续进行比较;
两边结果相同。
一个原本设计为“永远不应该通过密码验证”的账号,就可能被错误判定为认证成功。
Alpine 官方确认,这个问题不需要大量尝试,在符合条件的环境里可以稳定触发。
“没有密码”的账号,反而可能最危险
这次漏洞还有一个很反直觉的地方。
风险最大的并不一定是使用弱密码的账号。
反而是那些根本没有配置密码,只通过 SSH Key 登录的账号。
例如一些运维账号、自动化账号、云镜像默认账号。
管理员可能觉得:
“这个用户没有密码,所以密码爆破对它没有意义。”
正常情况下确实如此。
但这次漏洞恰恰把这个安全假设反转了。
“没有密码”不等于“PasswordAuthentication 已经关闭”。
这是企业排查时尤其要注意的地方。
只给用户配置 SSH Key,却仍然让 sshd 保留 PasswordAuthentication yes,和真正关闭密码认证是两回事。
为什么系统里还需要存在一个“正常密码账号”?
Alpine 官方披露的完整触发条件里,还有一个容易忽略的要求:
系统中还需要至少存在一个使用正常密码 Hash 的本地账号。
这个条件和 OpenSSH 十年前修复过的一次用户枚举问题有关。
2016 年,OpenSSH 修复 CVE-2016-6210 时,为了避免攻击者通过密码计算耗时判断“某个用户名是否真实存在”,会在一些没有正常密码 Hash 的情况下借用其他账号的 Salt 来做一次假的密码计算。
当时这个设计是为了让不同用户的认证耗时看起来尽可能一致。
十年以后,它却和 musl 的错误返回值、Alpine 的账号状态组合到了一起。
这次漏洞不是某一行代码突然写错,而是多个不同年代、各自看起来合理的安全设计最后拼出了一条认证绕过路径。
为什么 OpenSSH 和 musl 都说“根因不在我”?
这次还有一个挺有意思的技术争议。
OpenSSH 在安全公告里明确表示,他们认为根因位于 OpenSSH 之外,只是漏洞可以通过 sshd 被利用,因此 OpenSSH 很适合在自己这一侧快速做防护。
而 musl 维护者 Rich Felker 随后的说法也很直接:他认为这并不是 musl 本身的 Bug,而是调用方错误使用了返回结果。
两边其实并不完全矛盾。
一个库可以认为自己的错误返回值符合既定行为;调用者也可以认为这个行为非常容易被误解。
对于管理员来说,争论责任归属意义不大。
漏洞最终从 SSH 登录入口暴露出来,所以现在能做的,就是更新 OpenSSH 或关闭密码认证。
Alpine 为什么需要特别关注?
Alpine Linux 在容器、云主机、轻量服务器和各种 Appliance 里使用非常广。
很多团队选择它,就是因为镜像小、依赖少。
但这里要区分一个常见误区:
使用 Alpine Docker 镜像,不代表一定受影响。
绝大多数应用容器本来就不会运行 sshd。
真正需要重点检查的是:
以 Alpine 作为服务器系统、云主机镜像、跳板环境,或者在容器里额外部署了 sshd 的情况。
Alpine 官方已经为从 3.16 到 3.24 以及 Edge 的多个分支提供了修复包。
并且特别提醒:
更新 openssh 软件包以后,还必须重启 sshd。
只升级包但不重启,内存里运行的仍然可能是旧版本进程。
管理员现在应该先做什么?
第一件事其实非常简单。
如果不需要密码登录,就直接关闭。
PasswordAuthentication no
修改以后记得重启 sshd,并且在操作之前确认 SSH Key 登录正常,避免把自己锁在服务器外面。
第二,检查系统到底使用什么 libc。
如果是 Alpine 或其他 musl 系统,再确认 sshd 是否使用 PAM。
第三,确认真实生效的 sshd 配置,而不是只看配置文件里某一行。
企业环境经常存在 include 文件、自动化配置和镜像模板,最终运行状态未必和管理员印象一致。
第四,升级到发行版已经提供的修复包。
Portable OpenSSH 的修复版本是 10.6p2,但发行版通常会把补丁 Backport 到旧版本号上,因此不能简单通过 SSH Banner 判断是否修复。
已经暴露公网的机器,还应该回头查一次
升级只能解决接下来发生的问题。
如果一台符合漏洞条件的 SSH 服务器此前长期暴露在公网,最好顺手做一次历史登录检查。
Alpine 官方建议重点查看近期创建的用户、文件和 authorized_keys,以及是否存在异常提权行为。
如果日志里出现本来没有密码的账号却发生了密码认证成功,就应该提高优先级继续调查。
截至目前,OpenSSH 和 Alpine 的公开公告没有披露已经确认的大规模在野利用情况。
但这个漏洞的触发条件和技术细节已经公开,而且复现难度并不高。
没有公开在野利用,不等于可以等到下一个维护窗口再处理。
这次还有一个更值得注意的信号:AI 改变了漏洞披露节奏
这次 OpenSSH 发布补丁的速度非常快。
Damien Miller 表示,团队是在前一天才了解到这个问题,然后迅速完成修复并发布 10.6p2。
他给出的原因很值得安全行业关注。
OpenSSH 团队最近已经多次看到:
一个安全漏洞被报告之后,AI Agent 可能在数小时内独立重新发现同样的问题。
这也是为什么 Miller 认为,以前那种持续几周甚至几个月的漏洞禁运期,正在变得越来越危险。
过去留出较长时间,主要是为了让各家厂商同步准备补丁。
但 AI 漏洞挖掘能力上来以后,存在另一个风险:
安全团队知道一个漏洞,却假设外界暂时没人知道。
而另一个 Agent 可能很快从同一段代码里重新把它找出来。
AI 不只是在加快漏洞发现。
它也在压缩“漏洞被发现”和“其他人再次发现它”之间的时间差。
更有意思的是,这个漏洞本身也是 Agent 找出来的
漏洞发现者 Özgün Kültekin 在公开技术复盘中提到,他在测试 OpenSSH 与不同 libc、PAM 配置组合时使用了大量 Agent。
测试覆盖了 glibc、musl、PAM、非 PAM 等多种构建方式,并对认证逻辑进行了大量异常输入测试。
最后,几乎所有组合表现都一致。
只有一个例外:
musl + 非 PAM。
继续向下追以后,才找到了这个已经潜伏多年的组合问题。
这其实和最近很多 AI 安全研究呈现出的变化非常接近。
AI 不一定突然创造一种人类完全想不到的攻击方式。
它更擅长的是:
大规模组合测试;
快速比较异常差异;
反复验证边界条件;
从大量“看起来没问题”的结果里找出那个例外。
过去工程师可能不会专门花几天测试一万多种奇怪的登录输入。
Agent 可以。
写在最后
CVE-2026-123158 不是什么复杂的密码学突破。
攻击者没有破解 SSH 加密,也没有暴力破解出正确密码。
漏洞只是来自几个看起来都很合理的设计,最后产生了一个没人预料到的组合结果。
Unix 很早就用 * 表示一个不应该接受密码的账号。
musl 后来又用 * 表示密码计算失败。
OpenSSH 为了修复十年前的用户枚举,又调整过特殊账号的密码验证流程。
三个设计各自都有自己的历史原因。
直到 2026 年,它们终于撞在了一起。
这次漏洞最值得记住的,也许不只是一个 SSH 认证绕过。
还有一个新的现实:AI 正在让那些埋在代码里十年的边界问题,更快地被重新翻出来。
对管理员来说,动作倒很简单。
用 Alpine、musl Linux、OpenWrt、Buildroot 或 Yocto 的环境,先确认 SSH 到底怎么做密码认证。
不需要密码登录的,直接关掉。
需要密码认证的,尽快更新补丁。
对 SSH 来说,最可靠的“密码绕过修复”,很多时候就是根本不给密码认证留下入口。
参考资料
-
OpenSSH:Portable OpenSSH 10.6p2 Release Notes,2026-11-05
-
Damien Miller:Urgent security release: OpenSSH 10.6p2
-
Alpine Linux:Security advisory — openssh-server password authentication bypass
-
Özgün Kültekin / Wakefield:\*sshole technical write-up
-
musl mailing list:Advisory for OpenSSH + musl users
6. CVE-2026-123158 / NVD
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。











评论