本文へ移動
情シスの相棒
ニュース約8分で読めます

OpenSSHのsshole、AlpineなどmuslでPAMなしのsshdに攻撃の試み

OpenSSH 10.6p2で直ったssholeは、musl libcでPAMを使わないsshdだけに当たります。Red HatはRHELを対象外と明言しました。自社のAlpineのsshdを一度に探す方法と、版と設定の確認、止め方が分かります。

公開 更新 執筆・監修:佐々木 航人が監修しながらAIを活用して執筆
文字
OpenSSHのsshole、AlpineなどmuslでPAMなしのsshdに攻撃の試み

この記事のまとめ

  • ssholeが当たるのは、muslでPAMなしのsshdで、代表はAlpineです。
  • 直したAlpineも版の表示は10.6p2にならず、パッケージの版で比べます。
  • 攻撃の試みは7か国から11件。CISAのKEVには入っていません。
こんな方に#30代#40代#50代実務

RHELやDebian、UbuntuのようにglibcとPAMで動く普通のLinuxサーバーのOpenSSHは、今回の「sshole」の条件に当たりません。当たるのは、musl libcで動き、PAMを使わないsshdです。代表はAlpine Linuxです。

OpenSSHは11月5日に10.6p2を出し、この穴をふさぎました。番号はCVE-2026-123158です。翌6日から、脅威情報の会社Previdianが攻撃の試みを観測しました。

条件に当たるサーバーでは、パスワードを知らなくてもログインできてしまいます。外から届く所にAlpineのsshdがあるなら、今日のうちに確認したい件です。

「*」の欄に、ほかのアカウントのソルトを借りる

Alpine Linuxの勧告によると、攻撃に要るのは次の組み合わせです。

  • パスワードの欄が「*」のアカウントがある。鍵でしかログインしない運用なら、ふつうはこの形です。
  • 同じマシンに、$5$か$6$で始まるパスワードのハッシュを持つアカウントが1つ以上ある。
  • sshdのパスワード認証が有効になっている。OpenSSHの既定は有効です。

PAMを使わないsshdは、送られたパスワードをcrypt()でハッシュにして、shadowの欄と比べます。欄が「*」でソルトの無いアカウントでは、ほかのアカウントのソルトを借りて計算します。2つめの条件が要るのは、このためです。

muslのcrypt()は、256バイトを超えるパスワードでは計算に失敗し、失敗のしるしに「」を返します。この「」が欄の「*」と一致して、ログインが通ります。攻撃者が送るのは、257〜1,024バイトの長いパスワード1つです。

Alpine Linuxのセキュリティ勧告の画面。SSHのポートに届く攻撃者はパスワードを知らずにログインできること、パスワード欄が*のアカウントと、5か6で始まるハッシュを持つ別のアカウントが要ること、257から1024バイトの長いパスワードを送ること、影響を受けるのはPAMなしのopenssh-serverでPasswordAuthenticationがyesの場合で、rootは3.16のころからroot:*になっていることが書かれている。
Alpine Linuxの勧告。攻撃に要る条件と、影響を受ける構成出典: Alpine Linux「Security advisory: openssh-server password authentication bypass」(引用)

発見者のsshhole.comは、glibcのディストリビューション、PAMを通す構成、Dropbearは問題ないという見立てです。glibcの側は、失敗すると「*0」を返すためです。

見落としやすいのは2つめの条件です。鍵だけで運用していたマシンは、そのままなら狙えません。ところが、誰かがコンソール用や緊急用にパスワードを1つ設定した時点で、パスワードの無いアカウントすべてに入れる状態に変わります。

例は、Alpineの公式のクラウド用イメージ(tiny-cloud)です。3.18.11から3.24.3のイメージには、欄が「*」で、パスワードなしでdoasを使えるalpineユーザーがいます。管理者がコンソールのパスワードを設定すると、alpineで入ってdoasでrootになれます。

rootも、3.16のころからAlpineの基本のイメージではroot:*です。もっとも、OpenSSHの既定のPermitRootLogin prohibit-passwordが守るので、PermitRootLogin yesにしていなければ直接は入れない形です。

版の表示と、スキャナーの赤

11月7日朝の時点の扱いは次のとおりです。

ディストリビューション 扱い
Alpine Linux 影響あり。各ブランチに修正を当てたopenssh。3.24は10.3_p1-r2、3.23は10.2_p1-r1、3.22は10.0_p1-r11、3.21は9.9_p2-r1
Red Hat(RHEL) 対象外と明言。glibcにつなぎ、既定でPAMを使うため
Debian 修正はunstableの1:10.6p2-1だけ。緊急度は「unimportant」
Ubuntu 優先度はMedium。各リリースの状態は「Needs evaluation」

Alpineの修正は、10.6p2への更新ではありません。各ブランチの版に修正を当てたもので、3.24ならssh -Vは直す前も後も10.3p1と出ます。版の確認は、apk list -I 'openssh*'の結果を表と比べる形です。3.20〜3.16の版は勧告で確認できます。修正の入った小さな版(3.24なら3.24.4)以降で作ったイメージなら、直った状態です。

一方、CVEの記録の対象は「10.6p2より前のLinux」で、muslの条件がありません。そのため脆弱性のスキャナーが、直したAlpineも、RHELやDebian、Ubuntuも赤く出すことがありえます。RHELの赤は、Red Hatの説明どおり当たりません。

3.15以前のAlpineには修正版が無く、パスワード認証を止めるか、OSを上げることになります。

攻撃は「試み」の段階、点数で後回しにしない

PrevidianのCVEのページによると、11月7日朝の時点で観測した攻撃の試みは11件です。攻撃元のIPアドレスは8つ、国は日本を含む7か国でした。

ただし同じページは、観測は試みで、相手が脆弱だったことや攻撃が成功したことは示さない、と断っています。CISAのKEVにも、11月6日の版では入っていません。

それでも、待つ理由は薄いでしょう。CVSSは8.1で「攻撃の難しさ」は高い扱いですが、Alpineの勧告は「1回の接続で、毎回成功する」としています。CVEの記録には再現環境のリポジトリが2つ並び、CISAの評価も「実証コードあり」です。点数で後回しにすると、条件の当たるサーバーを見落とします。

自社のどこにAlpineのsshdがあるか、一度に探す

Alpineは軽いので、目立たない所で動きがちです。台帳で「Linuxサーバー」と1行にしていると、まず見つかりません。1台ずつ入る前に、外から当たりを付けます。

  • ネットワークの範囲をnmap -p22 --script ssh-auth-methods <範囲>で見ると、パスワード認証を出しているSSHが分かります。バナーで、OpenSSHか、Dropbearのような別のSSHサーバーかも分かれます。
  • 1台なら、ssh -o PreferredAuthentications=none -o BatchMode=yes <名前>@<ホスト>で返る一覧にpasswordがあるかを見ます。
  • コンテナはdocker psで動いているものを出し、イメージのスキャンやSBOMで、openssh-serverを含むAlpineのイメージを探します。中でsshdを動かしていなければ対象外です。
  • 機器では、発見者がOpenWrt、Buildroot、Yoctoの名を挙げました。バナーがOpenSSHなら、メーカーの更新を待つ間、パスワードのログインを止められるかを確認します。

cloud-initで設定したクラウドのイメージは、PasswordAuthentication noが書かれるため外れる、とAlpineは説明しています。

対象外のサーバーと、当たるサーバー

  • 当たる: Alpine Linuxなど、muslでPAMを使わないsshdを、パスワード認証を有効にしたまま動かしているサーバー。外から届くものを先に見ます。
  • 対象外: RHELやDebian、Ubuntuの標準のOpenSSH。スキャナーが赤く出しても、この件では当たりません。
  • 対象外: PasswordAuthentication noで動かしているsshdと、Alpineのopenssh-server-pamをUsePAM yesで使うサーバー。

今日確認すること、版と設定とshadow

  1. 版を見ます。apk list -I 'openssh*'が表の版より古ければ、apk upgrade -U -aのあとrc-service sshd restartです。パッケージを上げただけでは、動いているsshdは古いままです。コンテナは、docker build --pull --no-cacheでイメージを作り直します。
  2. 設定は、grep -ri passwordauthentication /etc/ssh/sshd_config /etc/ssh/sshd_config.d/でファイルの中を見ます。sshd -Tだけだと全体の既定しか出ず、Matchの中でyesにしたサーバーを見落とします。
  3. /etc/shadowは、awk -F: '$2=="*"{print $1}' /etc/shadowでパスワードの無いアカウント、awk -F: '$2 ~ /^\$[56]\$/{print $1}' /etc/shadowでハッシュを持つアカウントが出ます。ディレクトリから来る利用者(musl-nscd経由のnslcd、winbind、sssd)はここに出ませんが、勧告では対象です。片方だけのサーバーも、あとでパスワードが1つ増えれば当たるので、更新しておきます。
  4. すぐ上げられないサーバーは、パスワード認証を止めます。先に鍵でログインできることを確認し、今のセッションは開いたままにします。3.19以降は/etc/ssh/sshd_config.d/にPasswordAuthentication noのファイルを置けますが、3.18以前はそこを読まないため、sshd_configのMatchの中の行も含めてnoにします。sshd -t && rc-service sshd restartで試してから再起動し、新しいログインを試してから今のセッションを閉じます。

入られていないかを見る

外から届いていたサーバーなら、まず/var/log/messagesでAccepted password forを探す作業です。rootやalpine、鍵だけのはずのアカウントで出ていれば、入られた跡です。あわせて、doasの使われ方、最近作られた利用者やファイル、authorized_keysの変化も見ます。

コンテナには、ふつう/var/log/messagesがありません。ログが無いなら、入られていないとは言い切れないわけです。Alpineの勧告も、ログインを否定できなければ侵害された前提で扱うよう求めています。その場合は、ネットワークから切り離し、そのサーバーに置いていた鍵やトークンを替えてから、作り直します。

脆弱性の番号と評価の推移は、CVE-2026-123158(SecPulse)で追えます。10月のOpenSSHの別の脆弱性は、OpenSSHに型の取り違えの脆弱性、10.6未満の版と設定を確認で確認できます。

普通のサーバーが外れるからといって、後回しにするのは少し怖い件です。Alpineのサーバーほど、誰が立てたのか分からないまま動いていることが多いからです。

出典・参考

人が監修しながらAIを活用して執筆しています。公開したあとも、人が内容を確かめています。

執筆・監修

佐々木 航株式会社Game

代表取締役。工学部出身で、21歳で起業してからシステム会社の経営一筋で8期目。アプリの受託開発から始め、いまはAIを使ったシステムソリューションを手がけています。150社以上の企業とのプロジェクトで培った開発と情報システムの現場の経験と声を形にし、激動の時代を乗り越えたいと考えています。

記事は、人が監修しながらAIを活用して執筆しています。何を書くかと中身は人が決めて確かめ、記事の中身の責任は編集部(執筆・監修者)が負います。くわしくはAI の使い方に書いています。まちがいに気づいたら訂正・ご指摘からお知らせください。直したら更新日を改め、記事の最後に何を直したかを書きます。

役に立ったら、いいねと共有をお願いします