どさにっき 〜2017年4月上旬〜

by やまや
<< = >>

2017年4月6日(木)

SSH のホスト鍵検証

_ 子供のころ遊んだよね、忍者ごっこ。「アイコトバをいえ! やま!」「かわ!」

_ これ、セキュリティ的に重要な要素なんだけど、みんな忘れちゃったのか無視してるんだか。他人に知られてはならない重要な情報を伝達するにあたっては、まず相手が味方であることの確認からはじめなければならない。忍者の合言葉というのは、その味方の確認なわけだ。相手確認をサボって本来情報を伝えるべきでない相手に伝えてしまったら暗号化する意味がない。オレオレ SSL がダメなのは、この確認ができないから。そして、SSL だけではなく、SSH でも当然接続先の確認は必須である。

_ この SSH の接続先検証に関するオプションが StrictHostKeyChecking。これを no にする(検証しない)というのは、 SSL でいえば接続先の証明書を検証しない(不正な証明書でも気にせず接続する)というのと同じで、極めて危険。ホスト名で接続しようとしたらキャッシュ DNS に毒入れされてて意図せぬところにつながった、とか、そもそも経路をハイジャックされてた、とかのように MITM されてると認証情報やらログイン後のやりとりやらいろいろ盗まれるおそれがある。

_ なのに、とくに理由もなく StrictHostKeyChecking を no にするような記述が大量に存在している。このオプションにどんなリスクがあるのか理解した上で、あえてリスクを許容するのであればまあしかたない。でも、google の検索上位にひっかかったものの多くはせいぜい「リスクがあるよ」程度で、どんなリスクがあるのかまで言及してるものはほとんどない。まったく何も触れてないものもいくつか。

_ さらに、つい先日、openssh とはまったく別実装の go の ssh ライブラリがデフォルトで ssh ホスト鍵を検証しないことが問題になった。この件、おれはもっと前の昨年の12月の時点で気がついていて、でもホスト鍵を検証するコールバック関数をちゃんと定義できるような実装になってるんだし、それをサボってるライブラリ利用側の責任なんじゃね、と思ってた。が、実際にこのライブラリを使ってクライアントを書こうとしてた人が、他の人が書いたホスト鍵検証ルーチンを パクろう参考にしようと調べてみたら、 ちゃんと鍵検証してるものがひとつもないという惨状が明らかに。あまりにひどいので、ライブラリ側で 鍵検証コールバックを未定義で使うと強制エラーになるよう後方互換性をぶっこわす修正がなされ、 CVE-2017-3204が割り当てられた。

_ 実際のところ、ホスト鍵を検証しないために MITM で意図しないホストに接続させられてしまってヤバい情報を漏らしてしまう、なんてのはめったにない。MITM を現実的におこなうのは攻撃のハードルが非常に高い。でも、MITM のリスクがまったくないのであればそもそも暗号化などせず平文のままでも情報が漏洩することはなく、ホスト鍵の検証以前に ssh を使う意味がない。リスクがあるからこそ ssh を使うのに、通信相手の正当性検証という最初の一歩を怠っていてはまったくリスクを回避したことにならない。なんでこんなのがまかりとおっているのか。

_ つづく。


2017年4月7日(金)

脆弱性スキャナの脆弱性

_ つづき

_ vuls という脆弱性スキャナがありまして。よそのホストに ssh で接続して、中にインストールされてるものを調べて、既知の脆弱性が残ってないか探すツール。

_ 脆弱性を探すためのツールだけど、このツール自体に脆弱性がある。ssh で接続する先のホスト鍵を検証していない。 きのう修正された。それ以前のものは危険なので、git pull してビルドしなおすべし。

_ これ、go で書かれていて、ssh も go の ssh ライブラリを使っていた。ということで、 CVE-2017-3204に該当。CVE-ID は go のライブラリに割り当てられたけど、 前述のとおり、このライブラリにホスト鍵検証の機能がまったくないわけではないので、利用する側が検証をサボっていい理由にはならないと思ってる。間違った使われ方がされにくいようにした方がいいのはもちろんだけど、最終的には間違った使い方をしてる方の責任で、ライブラリ側に責任を押しつけるのはよくない。

_ vuls は go の ssh ライブラリだけでなく、ssh コマンドを利用することもできる。そっちを使う場合の引数はこんな感じ(修正前)。

	defaultSSHArgs := []string{
		"-tt",
		"-o", "StrictHostKeyChecking=no",
		"-o", "UserKnownHostsFile=/dev/null",
		"-o", "LogLevel=quiet",
		"-o", "ConnectionAttempts=3",
		"-o", "ConnectTimeout=10",
		"-o", "ControlMaster=no",
		"-o", "ControlPath=none",
ソースに -o StrictHostKeyChecking=no を埋め込むとか、さすがにこれは擁護しようがない。コマンドラインオプションでの指定は ~/.ssh/config での指定より優先されるので、こうなってると回避は不可能。ホスト鍵の検証なんかするもんかという強い意思を感じられる。これはもはやセキュリティホールではなくバックドアなのでは、と本気で疑った。結論としては、バックドアではなく素でやってたらしいよ(それはそれでおかしいだろ)。

_ ということで、vuls は ssh する方法を2通りから選択できるけど、そのどちらを選んでもホスト鍵を検証しなかった。

_ この件、昨年の12月にはじめて vuls をいじったその日のうちに発見している。git clone してコンパイルして最初の実行で ssh に成功して、いやおかしいだろ、と。vuls 用に新規に作ったユーザで、ホスト鍵のリストが空っぽなのに、なんで ssh に成功すんの? SSL ならばルート証明書がはじめから OS やらブラウザに組み込まれてるので、とくに何もしなくてもサーバ証明書の検証が可能で、だからこそ証明書の検証をサボっているような脆弱性が存在していても発覚しづらいんだけど、ssh にはそういう便利な仕組みはないんだから (*1)とくに何もしなければ検証できずに接続に失敗する or 警告が出るのが正しい動作であって、接続に成功したらむしろおかしいとすぐに気がつかなければいけない。だから、脆弱性を作りこんでしまった作者だけを責めたくはない。こんなわかりやすい欠陥に気がつかずに使い続けてるユーザもおかしくないか?

_ 以前の日記で vuls について触れたときにはこの件はすでに発見済みで、これはセキュリティに関するツールなのにこんなヒドいのありなんか、と腹を立てながらも感情を殺して書いたのがあの記述。その後、裏で作者に連絡して、さらに1月の janog の懇親会場で直接口頭ではやく直してくれ、とアピールして、でもずっと修正されず。最近になって go の ssh ライブラリの件が問題になり後方互換性をぶっこわす修正がされたおかげで vuls が動かなくなって、ようやく対応された。go の側で互換性を維持しない修正がなかったらまだ放置されてたんじゃないですかね。

_ まとめ。脆弱性スキャナを開発したり、それを使って自分の管理ホストの脆弱性をチェックするような意識高い系の皆さんでも、こんな基本的なセキュリティの欠陥を認識できない。

_ 追伸。 github のホスト鍵を確認したことのある者だけが vuls に石を投げなさい。


(*1): 厳密にいうと、そういう便利な仕組み(CA 認証)はあるけどほとんど使われていない。

脆弱性スキャナの脆弱性、その2

_ で、vuls の出力結果を webui で見やすく表示する vulsrepoっていうツールがありまして。

_ 単刀直入に言うと、こっちも脆弱性があった。javascript を注入可能。 この穴を踏んでた。 CVE-2016-1000241らしい。こっちは 今日修正完了

_ 脆弱性調査するのに実行するコマンドの出力結果が細工されていても、vuls はそれをチェックせず素通ししてしまう。そして vulsrepo は素通りした細工された結果をそのまま食ってしまう。で、vulsrepo (が利用していた pivottable.js) が入力のチェックをサボってるので、脆弱性スキャンの結果に javascript を含む出力をするように細工することで vulsrepo に対する XSS が可能だった。

_ 脆弱性スキャンされる側のホストがスキャン元に注入するという攻撃ベクトルなわけだけど、脆弱性スキャン対象のホストってのはとーぜん自分の管理下のホストであって、本来ならこんな攻撃が成功するような状況ならば XSS を許す WebUI をどうにかする以前に、飼い犬に手を噛まれる間抜けな状態を直すのが先決。そういう意味ではそれほど大きな影響のある穴ではなく、修正せず放置していてもそれほど問題ない。

_ しかし、これまで vuls はホスト鍵を検証していなかったので、意図せず悪意あるホストに接続してしまう可能性があった。信頼できるホストのスキャン結果しか食わないのであれば vulsrepo の脆弱性は放置しても危険ではないが、ホスト鍵の検証不備によりその前提は崩れる。結果としてこちらの穴の危険度も増すことに。まあ、MITM が必要なんでハードルは高いけどね。

_ この穴も見つけたのは昨年の12月。vuls をいじりはじめた翌日に発見。ホスト鍵を検証しない穴を見つけて、じゃあこの穴を利用して何ができるだろう、と考えて、スキャン対象からスキャン元にいたずらできるだろうか、と試してみたらビンゴだった、という経緯 。

_ まとめ。直さないより直した方がいいけど、それよりまず vuls の方を更新しましょう。


<< = >>
やまや