<前の日記(2005-10-11) 次の日記(2005-10-14)> 最新

おおいわのこめんと (2005-10-13)


2005-10-13

[Security] SSL 2.0 version rollback の件のFAQ

以下、SSLv3 は SSL 3.0 と TLS 1.0 (と TLS 1.1 draft) を総称します。

1. 修正すると TLS や SSL 3.0 と SSL 2.0 は同時に使えなくなるの?

いいえ。今回の修正の対象である「バージョンロールバック攻撃」は、あくまでも 「クライアントが SSL 3.0 以上で繋ごうとしているにも関わらず、 通信中継者が SSL 2.0 への降格を強制する」攻撃です。 今回の修正をしても、クライアントが SSL 2.0 しか使えないケース、 サーバが SSL 2.0 しか受け付けないケースでは、どちらも正常に SSL 2.0 で接続を確立できます。

ただし、SSL 2.0 には既知の脆弱性が知られていますので、 可能ならサーバ・クライアントとも SSL 2.0 を無効に設定することを 個人的にはお勧めします。

2. SSL_OP_ALL を使っていなければ問題ないの?
3. 特殊なオプションなら実際には影響ないんじゃないの?

SSL_OP_ALL 及び SSL_OP_MSIE_SSLV2_RSA_PADDING を使っていないケースでは、(少なくとも今回の修正に関連する) 問題は生じません。

しかし、調査した限り、OpenSSL を使う大半のアプリケーションは、SSL_OP_ALL を設定しています。 これは、マニュアルで SSL_OP_ALL は

SSL_OP_ALL
    All of the above bug workarounds.

It is usually safe to use SSL_OP_ALL to enable the bug workaround options if compati-
bility with somewhat broken implementations is desired.

と、明示的に「通常安全である」と書かれているからでもあります。

具体例としては、Apache なんかは影響をもろに受けます。 Debian で16個ほどOpenSSLをサーバ側として使っているソフトウェアを選び、 ソースコードをざっと一瞥した限りでは、 標準で SSL_OP_ALL を使っていないものは3つ (stone, ssmtp, sslwrap)、 SSL 2.0 が明示的に禁止されていて問題にならないものが 2つ (webfs, proftpd) でした。残りの11のプログラムは SSLv2 を有効にしている限りにおいて脆弱性の影響を受けそうです。

4. 実際何が起こっていたの?

今回の問題は、SSL 3.0 を実装する際、併用する SSL 2.0 実装に追加で組み込んでおくべきだった チェックが、実際には有効になっていなかったという問題です。

SSL 2.0 には、通信を確立するまでの交渉段階のパケットを改竄しても、 それを検出できない問題が知られています。SSL 3.0 以降ではこの部分の改竄防止機構が 実装されていますが、クライアントとサーバの双方が SSL 2.0 を サポートしている場合、クライアントから送る最初のパケットの情報を 「SSL 2.0 しか使えない」と改竄すると、SSL 2.0 のプロトコルが実行されるため、 SSL 3.0 の通常の改竄防止機構は役に立ちません。

そこで、SSL 3.0 以降では、SSL 2.0 を同時にサポートする場合に、 この「バージョン低下攻撃」を検知するための追加機構が設計されました。 これは、

  • SSL 2.0 において暗号鍵の元になる秘密情報はクライアントからサーバへ RSA 暗号化で送信されるが、その際盗聴による推測を防ぐため、 (padding として) 乱数を一緒に暗号化して送ることになっている。 SSL 3.0 以上をサポートするクライアントが SSL 2.0 で通信する場合、 このパケットに含まれる「乱数」パディングの一部に、 8バイトのランダムでない特殊な符号を埋め込んでおく。
  • SSL 3.0 以上をサポートするサーバが SSL 2.0 で通信している場合、 RSA 復号したデータのパディング部分にこの特殊な符号があった場合、 不正な通信が行われているものとして取り扱う。

という仕組みになっています。このようなコードを v2 の実装部分に組み込んでおくことで、 実はサーバ・クライアントの4通りの組み合わせ全てでうまく接続できます。

双方が SSL 3 以上を使える場合(SSL 2 で通信していてはオカシイ場合)
攻撃によって v2 プロトコルにダウングレードさせられそうになると、 クライアントが符号を埋め込み、サーバが検知するため、接続を拒否する(ダウングレード攻撃が失敗する)。
サーバだけが SSL 3 以上を使える場合
クライアントが符号を埋め込まないため、正常に SSL 2 で通信が成立する。
クライアントだけが SSL 3 以上を使える場合
クライアントが埋め込んだ符号をサーバは単なる乱数だと思って読み飛ばすので、正常に SSL 2 で通信が成立する。
どちらも SSL 2 しか使えない場合
クライアントが符号を埋め込まないため、正常に SSL 2 で通信が成立する。サーバも検知しようとしない。

しかし、どうやら昔の Microsoft Internet Explorer 3.02 には、 「SSL3 のサポートを明示的にオフにした場合でも、符号を埋め込んでしまう」 というバグがあったようです。*1 この場合、実際には改竄が行われず SSL 2 で通信されるのが正しい場合でも、 サーバ側が符号を検知してしまい、通信が失敗します。 このバグの対処として、サーバ側で符号を検知しないオプション SSL_OP_MSIE_SSLV2_RSA_PADDING が実装され、 また当時の状況から SSL_OP_ALL にも含めることになったのではないかと思われます。 いずれにしても、9年ほど経過した現在では不要かつ有害な対処ですので、削除するのが理に適っているでしょう。

5. 実際のところ、そんなにやばいの? SSL3.0 で通信していれば問題ないんでしょ?

クライアントが SSL 3.0 と SSL 2.0 を両方有効にしている場合、 自分が SSL 3.0 で安全に通信しているつもりであっても、サーバ側に脆弱性があると、 パスワードなどを送ろうとした瞬間に突然接続を 40bit SSLv2 に切り替えられる危険性があります。

接続が SSL 2.0 に切り替えられることによって生じる脆弱性については、9月10日の『SSL 2.0 と輸出強度暗号』、9月23日の『40ビット暗号の攻撃可能性』等をご覧ください。

逆に言えば、クライアント側で SSLv2 を無効に設定していれば、サーバ側の OpenSSL に脆弱性が存在しても 問題ありません。また、クライアント証明書を使っていない場合、 SSLv2 の弱暗号を無効にしていれば、最大の危険性である 暗号解読の被害をかなり軽減できると考えることも可能でしょう。

なお、SSLv3 の輸出強度暗号(弱い暗号)は、 (解読の危険性はv2と変わらないので利用を全くお勧めできませんが、) 今回の脆弱性とは無関係です。 例え v3 の弱い暗号を有効に設定していても、v3 の強い暗号で通信できる相手同士が 今回の脆弱性によって v3 の弱い暗号で通信させられる可能性はありません。

6. どうやって調べたの?
7. どうやったら攻撃できるの?

調査する時点では、Perl で10行くらいの proxy 作って、 明示的にそこに接続させて試してます。試すだけならいわゆる ネットワーク上での中間者攻撃をする必要は無いですから。

実際にこの脆弱性を悪用するためにはネットワーク上でパケットに 悪戯をする必要がありますが、その方法についてはお答えできません :-P

8. 回避する方法はないの? 具体的な設定方法は?

OpenSSL のバージョンアップ、パッチ適応の他に、以下のような回避策が可能です。

8-1. クライアント側の対処

10/11に書いた通り、SSLv2 を無効にすることで、ダウングレード攻撃を無効化できます。副作用として、SSLv2 でしか繋がらないサイトには接続できなくなります。大多数の Web ブラウザでは、使用する SSL のバージョンを設定ダイアログから選択できます。

なお、この設定や今回の OpenSSL 側のバグ修正は、どちらも 「SSLv3 の強い暗号で繋がるべきサイトに、弱い暗号で接続してしまう」ことを防止する効果しかありません。 「弱い暗号しかサポートしていないサイト」に接続する際には、弱い暗号で接続してしまいます (そして、同様の解読の脅威があります)。 また、サーバ側が SSLv2 しかサポートしない場合には、暗号ダウングレード攻撃は今回の修正の後でも 依然として可能です(これは、プロトコル上回避できない)。

弱い暗号プロトコルで通信されることの脅威を本質的に無効化するためには、 SSLv2 と弱い暗号の両方を無効化することをお勧めします。

具体的な方法については、例えば

等をご覧ください。Opera にも(少なくとも Windows 版 8.50 には)同様の設定が可能なダイアログがあるようです。 (IE については、 9/25 で 触れていますが、副作用の危険性が高いためあまり推奨しません。 内部で何を設定変更しているのかを理解できた人以外は、 とりあえず SSLv2 を無効にするだけにしておきましょう。)

8-2. サーバ側の対処

サーバ側でも、SSLv2 を無効化することで、ダウングレードを実質的に防止できます。 内部的には OpenSSL では、「SSLv2プロトコルを無効化する」「SSLv2の暗号を全て無効化する」の 2つの設定が可能で、ごくわずかに挙動が変わりますが、どちらでも攻撃を防げます。

具体的な方法については、サーバアプリケーションによります。たとえば、Apache については gmt-24 さんが試しています。 SSLProtocol の行と、SSLCipherSuite の行が上記のそれぞれの設定に相当します。

あるいは、SSL_OP_ALL に相当する動作の有無を明示的に指定できるアプリケーションでは、 該当オプションを「使わない」方向に設定することでも回避できます。 例えば、sslwrap や openssl s_server では、 -bugs オプションを使わない限り、今回の問題は発生しません。

*1 手元で MSIE 3.02 で試せないかいろいろ探したんですが、古過ぎて環境を発掘できませんでした……。

[TrackBack URL: http://www.oiwa.jp/~yutaka/tdiary/trackback.rb/20051013 (note: TrackBacks are moderated: spams will not be shown.) ]

大岩 寛 (おおいわ ゆたか) <yutaka@oiwa.jp.nospam ... remove .nospam> .

Copyright © 2005-2014 Yutaka OIWA. All rights reserved.
Posted comments and trackbacks are copyrighted by their respective posters.

記事の内容について (Disclaimer / Terms and Conditions)