新版本 0.5.11

目前 0.5.10。產生此頁時偵測到新版本。

這次更新:

在終端機執行:

npx skills update answer-me-with-html -y

或者告訴 Agent:

更新 answer-me-with-html
查看更新內容

Generated by Answer me with HTML 0.5.10 · 2026-11-06 17:12 · ★ Star on GitHub

sshhole — 257 個 A 就能登入的十年老洞

musl 的 "*" 與 OpenSSH 的假驗證,串成一個 SSH 登入繞過

sourcesshhole.com · Hacker News 2,669 分 / 635 則留言 (2026-11-06)

Lead: 在 musl、無 PAM 且開啟密碼登入的 sshd 上,257 到 1024 個字元的任意密碼能登入 "*" 帳號。OpenSSH 10.6p2 已修補(CVE-2026-123158)。

A

攻擊鏈

超過 256 bytes,回傳 "*"攻擊者送 257 個 Amusl crypt()musl 回傳 "*"sshd 拿它與帳號欄位比對比對成功登入 "*" 帳號

每一步單看都合理。串起來就是繞過。

B

時間線

  1. 1980第一個星號Bill Joy 在 3BSD /etc/passwd 把 daemon 帳號設為 "*"
  2. 2012 年 8 月musl 改回 "*"crypt() 出錯不再回 NULL,改回 "*"
  3. 2012 年 8 月下旬加 256 bytes 上限sha512crypt 拒絕超長密碼,三週後上線
  4. 2016 年 7 月OpenSSH 借 salt假驗證讓不存在的帳號也耗時相同
  5. 2019Alpine 鎖 rootCVE-2019-5021 用 "!" 鎖死 root,keys 一併被殺
  6. 2022Alpine 換成 "*""!" 改成 "*" 鎖 root,keys 恢復
  7. 2026 年 10 月 30 日審查修 pick_salt真 bug 在其下方四行,未被修掉
  8. 2026 年 11 月測出漏洞agent swarms 丟出 17,600 次怪異登入
C

觸發條件

條件 為什麼必要
sshd 跑在 musl glibc 失敗回傳 NULL,不會產生 "*"
不走 PAM 有 PAM 時 "*" 帳號不會進 crypt()
密碼登入開啟 關閉密碼登入就免疫
有 "*" 帳號 無密碼可比對的帳號才是受害者
另有真密碼帳號 sshd 借它的 salt 做假驗證
D

誰安全誰中招

情境 結果
Alpine 官方 AWS/Azure 映像 可能中招:預設 alpine 帳號為 "*" 且免密碼 doas
OpenWrt 預設 dropbear 安全:不用 OpenSSH
Debian / Ubuntu / Fedora 安全:glibc
OpenBSD 安全
有 PAM 的環境 安全
E

修補方式

立即升級

apk upgrade openssh

升級到 OpenSSH 10.6p2 即修好。無法升級時關掉密碼登入:

暫時對策code
echo "PasswordAuthentication no" > /etc/ssh/sshd_config.d/00-no-passwords.confrc-service sshd restart
F

HN 討論分歧

面向 正方 反方
錯誤該怎麼回報 回 NULL 讓呼叫端 crash,問題才會浮現 生產環境不能為沒檢查的呼叫端崩潰,libc 只能遷就
根因是不是語言 C 缺 Result 逼人用 sentinel,bug 不該存在 換哪種語言都寫得出相容性藉口,問題在 ABI 包袱
嚴重度 條件全是預設值,基數龐大 容器通常不跑 sshd,實務上極不可能
是否蓄意 挑 "*" 又三週後加上限,巧合太多 可挑的字元本來就那幾個
G

實測筆記

  • Alpine 官方映像已於發現當天更新,舊版重現要先降級 OpenSSH
  • "*" 帳號第一次失敗,第二次(含)超長密碼才通過
  • Alpine 3.15 手動把 "!" 改成 "*" 後可重現
  • Forgejo 要開密碼登入並新增真密碼帳號才觸發,預設安全