1. はじめに

いや〜、今年は脆弱性対策が当たり年ですね〜〜。(トホホ)。 bash ShellShockの対策も継続して観察しているなか、 新しいPOODLEというSSLv3プロトコルに関する脆弱性が出てしまいました。 子犬のプードルだって!可愛くないっつ〜〜の!! SSLv3プロトコルのパディングの問題点を突いて、効率的に暗号文を 復号できしまうので、例えばセッションクッキーを復号して通信を盗聴することが できるのだそうです。 POODLEはPadding Oracle On Downgraded Legacy Encryptionの略だそうで、 パディングオラクルとはパディングを含む暗号文を入力として送りつけると、 そのパティングが正しいかどうかを返してくれるブラックボックスのような 計算機のこと。 SSLv3みたいなできて15年にもなる弱い暗号通信プロトコルに、 強制的にダウングレードさせて、 オラクルに対して何回もいろいろ入力を変えて試行して、 エラーメッセージなどどう反応するかを見る事で、 暗号文の解読を試みるという攻撃です。

気がついたまでの経緯は当日どんな感じだったかというと、日本時間で10月15日の23:30頃、 The Registerの「NASTY SSL 3.0 vuln to be revealed soon」の記事を見つけていまい、こりゃ、やばげだなと。知り合いに明日ヤバイのがまた来そうと連絡しました。TLS 1.0とSSL 3.0とバージョン番号が違うだけだと言い張る人も多い中、Macとか、パディングとかそのちょっとの違いが仇になるんじゃないかと、ずっと気になってたんですが、とうとう来たかと。詳細情報は夜が明けないとわからないので、半分 wktk しながら寝て待ってたんですが、朝になって、Googleのブログ 「This POODLE bites: exploiting the SSL 3.0 fallback」が出てきたものの、わかったことはプードルという可愛らしい攻撃の名前と、GoogleサイトとChromeはとっくにTLS_FALLBACK_SCSVに対応しているぜ!みたいな。 自慢かっ?技術詳細なく自慢だけなのかっ!と憤りつつ、しばらく待ってると、 やっと安定のImperialVioletで 「POODLE attacks on SSLv3 (14 Oct 2014)」 技術解説が出たのを見て、こりゃマジやべ〜〜な、と・・・ その後、情報のとりまとめにいそしんでおりました。

この記事では、様々なHTTPSサーバーに対するPOODLE脆弱性対策の 方法について、まとめておきたいと思います。

2. SSLv3を無効化できる場合のサーバー対策

古いガラケーや、一部のゲーム機や、古い環境でのAPI利用などを除いて、 一般のブラウザであればSSLv3でしか通信できないという事は無いので、 SSLv3を無効化するというのが、一番正当なPOODLE対策であると思います。 この章では、SSLv3を無効にするために、 サーバーのソフトウェア毎にどのように設定すればよいかをまとめます。

2.1. Apache HTTPD Server + mod_ssl

httpd.confやssl.confに

SSLProtocol All -SSLv2 -SSLv3
と記載しサーバーを再起動 (※Apache 2.4以降はSSLv2は無効)

2.2. Apache HTTPD Server + mod_nss

nss.confもしくはhttpd.confで

NSSProtocol TLSv1.0,TLSv1.1
と記載しサーバーを再起動

2.3. nginx

ssl_protocols TLSv1 TLSv1.1 TLSv1.2
と記載しサーバーを再起動

2.4. lighttpd

lighttpd 1.4.28 以降を使用。それ以前ではSSLv3を無効化できません。

ssl.use-sslv2 = "disable"
ssl.use-sslv3 = "disable"
と記載しサーバーを再起動

2.5. Microsoft IIS

コマンドラインで以下を実行することで、レジストリ設定により無効化します。 (参考 [1] [2] [3])

reg add "HKLM\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server" /v Enabled /t REG_DWORD /d 0 /f
reg add "HKLM\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server" /v Enabled /t REG_DWORD /d 0 /f

2.6. Apache Tomcat (Java JSSE)

Apache Tomcatというか、JavaのSSL通信拡張であるJSSEの SSLプロトコル設定では、SSLv3を無効化することができません。

Tomcatの設定ファイル "server.xml"の"Connector"要素において、 Tomcat 5および6ではsetEnabledProtocol属性、 Tomcat 7以降ではsetProtocol属性を使えばSSLプロトコルを指定 することができますが、 例えば、JDK 7 を使用した場合、 設定する値、実際のサポートプロトコルのまとめは以下の通りであり、 現時点ではどのように設定しても SSLv3 を無効化することができないようです。 (参考 [4])

属性値/値実際に設定される受入れプロトコル
setProtocol="TLS" SSLv3, TLSv1
setProtocol="TLSv1.2"SSLv3, TLSv1, TLSv1.1 TLS v1.2
setProtocol="TLSv1.1"SSLv3, TLSv1, TLSv1.1
setProtocol="TLSv1" SSLv3, TLSv1
setProtocol="SSL" SSLv3, TLSv1
setProtocol="SSLv3" SSLv3, TLSv1
setProtocol="SSLv2" エラー
従って、2.1節で述べる暗号スイートの設定 による緩和策しか現時点では手がないようです。

検索するとsetProtocol="TLSv1"のようにすればよいと書いてある サイトもあるようですが、コメントされているように 効果が無いので注意が必要です。 (参考 [5])

2.7. Node.js

Tomcat同様これもインターネット直出ししている事はないと思いますが 以下の実装例のようにsecureOptionsでSSLv2,SSLv3を使用しないよう設定が可能です。 (参考 [6])

var constants = require('constants') , https = require('https') , path = require('path') , tls = require('tls') , fs = require('fs'); https.createServer({ secureProtocol: 'SSLv23_method', secureOptions: (constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_SSLv2), cert: fs.readFileSync(path.join(__dirname, 'ssl', 'server.crt')), key: fs.readFileSync(path.join(__dirname, 'ssl', 'server.key')), }, function (req, res) { res.end('works'); }).listen(443);

2.8. その他のサーバー

その他のサーバーについては、以下を参考にしてみてください。

2.9. SSLv3 を無効化するリスク

現在サポートされているPCやスマートフォンのブラウザではTLSv1.0以降 がサポートされているので問題にならないと思いますが、 例えば、2007年秋以前のdocomoのガラケーやSONY PS3では、SSLv3しかサポート していないことを実機で確認しています。 古いガラケー、ゲーム機、組込み機器に対応するウェブサーバーを 運用する場合には、接続できずクレームになる可能性もありますので、 クライアント側の対応環境を確認すると良いと思います。

また、ウェブサーバーをAPIで利用する場合にも、どのような環境、 言語実装を使うかで問題があるケースがありますので、 確認しておくと良いと思います。TwitterやFacebookも API利用されているためにトラブルになったそうです。

3. 諸般の事情で SSLv3 を有効にせざるを得ない場合

一般的なブラウザに関してはSSLv3を無効化する方向で進んでおり、 ウェブサイトでもSSLv3を無効化するのが、正しい対応だと思いますが、 古い環境をサポートしなければならないために、SSLv3を有効に しておかなければならないケースもあると思います。 3章では、SSLv3をサポートしなければならないケースでの、 脆弱性の緩和策について説明したいと思います。

3.1. 暗号スイート設定で対処する方法

POODLE脆弱性はSSLv3とブロック暗号のCBCブロックモードを使用した 場合に影響があるので、暗号スイートとして以下を選択することで 問題を緩和することができます。

  • 認証付暗号化方式(AEAD)であるGCMブロックモードの暗号スイートを使用する
  • ストリーム暗号(RC4,ChaChaなど)を使用する
古いガラケー、ゲーム機、組込み機器、API利用など、SSLv3を 使わなければならないような環境では、GCMモードを使うこともできず 暗号スイートとしてTriple DESかRC4の選択肢がありません。

RC4ストリーム暗号は、現実的な時間内に部分的に解読することが 可能な危殆化した暗号で使用すべきでないとされていますが、 POODLE脆弱性は適用条件や解読にかかる手間が極端に少ないので、 Triple DESをCBCモードで使うよりもRC4の方が、まだ安全であると 言えます。

従って、
  • TLS_RSA_WITH_3DES_EDE_CBC_SHA を含む全ての暗号スイートを無効化
  • その上で、TLS_RSA_WITH_RC4_128_SHA のみを有効化
  • 同時に新しめのクライアントも環境もサポートしたいならGCMの暗号スイートを有効にする
するぐらいしか手がありません。

ただし、マイクロソフト製品では2014年8月のアップデート以降、RC4は無効になっていますので、 Windows系のサーバー機を使用する場合には、Apacheなど他のサーバーを使う必要があるでしょう。

Apache Tomcatを直接インターネットに出していることも少ないと思いますが、 前述の通りTomcatやJSSEを使うJava実装のSSLサーバーでは SSLv3を止める手段が現状無いために、暗号スイートにRC4のみに 設定するしか緩和策がありません。

3.2. TLS_FALLBACK_SCSVを使う方法(現時点で極めて限定的)

SSL/TLSで通信を開始した直後はTLSv1.0以上で問題ない接続であったとしても、 ある種の攻撃により脆弱なSSLv3.0以下にダウングレードさせる攻撃があります。

これを、防ぐための新しく提案されている仕組みが TLS_FALLBACK_SCSV オプションを使う方法です。これをサーバーとクライアントの双方が サポートする場合、TLSからSSLv3.0以下に強制ダウングレードさせることは できなくなります。

ただ、これをサポートしている環境は現時点(2014.10.18)では非常に限定的です。

  • クライアント
    • Google Chromeのみ
  • サーバー
    • 最新の2014.10.15リリースのOpenSSL 1.0.1j/1.0.0o/0.9.8zcを利用するApache,Nginx,Lighttpdなどのサーバー
    • Google提供のサービス(2014年2月頃からサポートしていたらしい)
以下のような条件のサーバーを必要としている場合で、 TLS_FALLBACK_SCSVをサポートする環境なら導入を検討しても よいかもしれません。
  • CBCブロック暗号モードをどうしても使う必要があり、
  • TLSで最初接続できた利用者にはSSLv3ダウングレードせず安全に使用して欲しい。
  • SSLv3で接続してきた利用者にはリスクを承知でCBCモードで接続してもらってもよい。
SSLv3を無効化できるか、3.1節の対策が取れるならば、 OpenSSLの今回のアップデートや、TLS_FALLBACK_SCSVの導入はあまり 気にする必要が無いと思います。

4. おわりに

以上、SSLサーバーでPOODLE脆弱性対応をする方法について、いろいろなサーバー 毎にまとめてみました。参考になればうれしいです。今日は、こんなとこで。

SSLv3のパディングについては、いろいろ勉強したので、近いうちに記事にできるといいなと思っています。