对 Linux 服务器来说,最完美的噩梦场景莫过于攻击者只需连上服务器的 Secure Shell (SSH) 端口,大摇大摆地走进去,然后接管一切。Alpine Linux 就遭遇了这种事——这款广受欢迎的轻量级 Linux 服务器。更扎心的是,就在几天前,Alpine Linux 才刚刚躲过一劫,其 GitLab 实现险些被一个安全漏洞击中。

正如安全工程师 Gregory Bryant 在领英帖子中所解释的:“大多数身份验证绕过都源于复杂的逻辑链,但昨天 Alpine Linux 的 OpenSSH 漏洞(CVE-2026-123158)归根结底就是一个字符:*。”

如果你运行的是 Alpine Linux(或其他基于 musl 的发行版),使用默认的 openssh-server 包(没有可插拔认证模块,即 PAM),并且启用了 PasswordAuthentication,那么攻击者只需发送一个长度在 257 到 1024 字节之间的密码,就能登录到禁用了密码或仅使用密钥的账户。

Alpine Linux 并不是唯一使用 musl 的操作系统——musl 是标准 C 库(libc)的轻量级版本。其他使用 musl 且可能受影响的系统包括 Adélie Linux、Void Linux、Sabotage Linux、OpenWrt(一个 Android 变体)以及用于构建嵌入式 Linux 发行版的 Yocto 项目。

生产商业嵌入式 Linux 发行版 Wind River Linux 的 Wind River 公司也在调查此问题。一位公司代表告诉我:“Wind River 严肃对待安全问题。我们正在积极审查所报告的漏洞并评估其潜在影响。我们将根据需要采取适当行动。”

在幕后,当 OpenSSH 在未使用 PAM 的情况下构建时,它通过使用 C 库的 crypt() 函数对尝试的密码进行哈希来验证密码。然后将结果与账户存储的密码字段进行比较。到目前为止,一切正常。

但是,当密钥长度超过 256 字节时,musl 的 crypt() 函数会返回字符串 * 作为错误指示。这也正是任何没有密码的账户(例如仅使用密钥的账户)的密码字段所保存的内容。因此,“哈希”匹配,登录成功,攻击者便溜了进来。

要利用此漏洞,攻击者只需要知道这样一个账户的名称。攻击者还需要机器上至少有一个其他账户拥有 5 或 6 哈希的密码,然后发送一个 257 到 1024 字节的密码。根据 Alpine 的说法,只要有一个用户设置了密码,就足以让所有无密码账户变得可访问。

在使用 glibc 的 crypt() 的 Linux 系统上(几乎所有的系统都是如此),同样的尝试会在出错时返回 NULL,而 sshd 已经会拒绝这种情况,因此 Debian、Ubuntu、Fedora 等不受影响。

据发现该问题的组织 *sshole 称,这是一个自 2016 年以来就一直隐藏着的副作用。

Alpine 表示,它检查过的每个版本都受影响:3.21 到 3.24、edge,以及更旧的 3.16 到 3.20 分支。暴露需要满足以下条件:

大多数情况下,root 不会直接暴露。自大约 Alpine 3.16 起,基础镜像中就以 root:* 的形式提供,但 OpenSSH 默认的 PermitRootLogin prohibit-password 会阻止它。另一个可以成为 root 的账户(例如通过 doas)仍然为攻击者提供了通往 root 的路径。

Alpine 特别指出其官方的 tiny-cloud 镜像(版本 3.18.11 到 3.24.3)尤其脆弱。这些镜像附带一个密码字段为 * 的 alpine 用户和无密码的 doas。它们在首次启动时是安全的,但一旦机器上存在任何 6 哈希,就会变得可利用。这可能在管理员设置控制台密码或用户数据添加带有哈希密码的用户时发生,这意味着基本上所有情况都会如此。

Alpine 于周四发布了 3.21.10、3.22.8、3.23.8 和 3.24.4,其中包含 OpenSSH 修复作为安全更改之一。它还发布了针对每个版本(回溯到 3.16)的修复包。Alpine 3.21 已于 11 月 1 日结束支持。

刚刚发布的 OpenSSH 10.6p2 在 sshd 中避免了该问题。Alpine 的稳定分支携带了针对同一问题的补丁。你应该运行 apk upgrade -U -a,然后重启 th