技術者ブログ

クラウド型WAF「Scutum(スキュータム)」の開発者/エンジニアによるブログです。
金床“Kanatoko”をはじめとする株式会社ビットフォレストの技術チームが、“WAFを支える技術”をテーマに幅広く、不定期に更新中!

2017年3月

      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
  • お問い合わせはこちら
Scutum開発者/エンジニアによる技術ブログ WAF Tech Blog

POODLE攻撃の検知とJavaによる検証コード

はじめに

SSLv3のパディングに注目した攻撃手法であるPOODLEは、以前こちらのブログのエントリで取り上げたことがあるBEASTCRIMEに非常によく似た攻撃です。今回はこのPOODLEについて、一般的な視点とはやや異なる、筆者独自の意見を述べてみたいと思います。

必ずしもSSLv3を無効にする必要はない

POODLEの対策として書かれている情報はそのほぼ全てが「SSLv3を無効にする」というものですが、個人的には技術的にもう少し踏み込んで考えてみても良いのではないかと感じます。私は以前のエントリで次のように指摘しています。

BEASTもCRIMEも、意図しないリクエストが飛ばされ、そこにCookieが自動的に含まれてしまう点を攻撃するという意味で、CSRF攻撃の一種だと言えるでしょう。BEASTが発表されたらBEAST対策(RC4にする/TLSをバージョンアップする)を行い、CRIMEが発表されたらCRIME対策(圧縮機能をオフにする)を行う、といういたちごっこよりも、より根本的な対策が求められている気がします。

  • 第三のサイトによって発生させられるリクエストに、自動的にCookieが付加すること
  • たったひとつのCookieの値でセッション管理を行うこと
  • ブルートフォース攻撃を行うような、似たリクエストの連続送信をサーバ側が許可すること

上記のような点について、ブラウザやウェブアプリケーションができることはまだまだあるはずです。たとえばウェブアプリケーション(あるいはミドルウェア)が、Cookieの値を非常に頻繁に変更するような動作を行えば、BEASTもCRIMEも通用しません。また、ブルートフォース攻撃を行うような、短時間に似たリクエストが大量に発生すること自体を検出できれば、それによって攻撃の検知と防御ができる可能性もあります。

POODLEに対しても上記が完全に当てはまります。POODLEの攻撃対象となるのは、ほぼ「HTTPリクエストにCookieとして含まれるセッションIDの値」に限定できます。そのため、例えばウェブアプリケーションがCookieを使っていない場合などには、そのサーバにおいてはSSLv3を無効にする必要はありません。また、Cookieを使っている場合でも、値を頻繁に変更するような工夫を行っていれば、それ自体がPOODLE(だけでなくBEASTとCRIEMについても)対策となるので、やはりSSLv3を無効にする必要はありません。

BEASTが出てきた時点で、攻撃者が平文の一部をコントロールでき、かつ大量の通信を発生させることができるHTTPは、TLS/SSLと非常に相性が悪いことが判明しましたが、この大きな理由はリクエストに自動的にCookieが付加されてしまうからです。逆に言えば、Cookieのひとつの値に大きく依存していなければ問題ないわけです。場合によってはメールサーバまでPOODLEの影響を恐れてSSLv3を無効にしているケースなどもあるかと思いますが、現実的にはメールサーバに対してPOODLE攻撃が行われることはありません。

また、最近では少ないかもしれませんが、セッションIDをhiddenの値として引き回す形のウェブアプリケーションでも、POODLE対策は必要ありません。

セッションIDの頻繁な変更

もしもアプリケーション処理への毎HTTPリクエストごとにセッションIDを変更するようなフレームワークがあれば、そのフレームワークを選択するだけで、BEAST/CRIME/POODLEのような攻撃を未然に防ぐことができます(HTMLに含まれるCSRFトークンが攻撃対象となる場合もありますが)。

BEASTが出てきたらブロック暗号を避けたり、CRIMEが出てきたら圧縮を無効にしたり、POODLEが出てきたらSSLv3を無効にしたり、というのはいたちごっこ的なアプローチであり、根本的な対策のためにはむしろCookieに含まれるセッションIDやHTML中に含まれるCSRFトークンなどの、リクエストやレスポンスに含まれる重要な情報の扱い方に注目するべきです。

「セキュアである」ことをウリにするような次世代のウェブアプリケーションフレームワークには、ぜひとも「セッションIDの頻繁な変更」をその機能として検討して欲しいと思います。

POODLEは検知できるか

さて、実際に(SSLv3が有効になっている)サーバに対してPOODLE攻撃が行われたら、それを検知することは可能でしょうか。筆者はこれをテストするために、JavaでPOODLEの検証コードを書いてみました。なお、このコードを完成させることができたのはDeNAのはるぷさんが公開してくれたこちらのブログエントリのおかげです。感謝します。

この検証コードは以下のようなものです。

  • Java7で動作を確認している
  • 本物のSSLv3、AESの通信で復号できることを確認することができる
  • 1バイトだけ復号したら終了する(現実の攻撃ではセッションID全体を復号するが、そのあたりの面倒な実装はしていない)
  • データサイズ等が決めうちになっている箇所が多いので、本物のネットワーク上で動かない可能性がある
  • 復号部分だけを検証する目的なので、現実の攻撃で用いられるであろう、ブラウザに読み込ませるコードは含まれない

POODLE攻撃は大量のリクエストを送信し、1/256の確率で1バイトの復号に成功します。たまたま、復号されたデータのパディング長部分が15(AESのようにブロック長が16バイトの場合)である場合に攻撃が成功します。このときはサーバ側のAESの復号処理はエラー無しで終わり、ウェブサーバ側にはアクセスログも残ります。

255/256程度の高い確率でAESの復号処理が失敗します。このとき、SSLサーバ側の実装がJava7の場合には、Invalid SSLv3 padding、Invalid Padding length、あるいはbad record MACといったメッセージを含む例外が送出されます。これらの例外は正常時には殆ど発生しないものであるため、POODLE攻撃が行われたかどうかはこれらの例外をキャッチすることで検知が可能です。

この際、クライアントにはAES復号処理のエラーを通知するための暗号化されたSSLのAlertレコードが送られます。このレコードは暗号化されてしまっているため、ネットワーク上のIDSやIPSは正確にはそれがPOODLEの失敗のせいなのかどうかを判断することはできませんが、正常時とSSLエラーレコードの発生頻度が異なるかどうか等で検知することができる可能性は十分にあります。筆者が確認した感じでは、SnortのPOODLE検知のシグネチャはそのような内容になっているように見えました。

POODLEはTLSにも影響するかどうか

既に報じられているようにいくつかの主要セキュリティベンダーも含むTLS実装が主にパフォーマンス上の理由からTLSにおいてパディング処理を正確に実装しておらず、TLSにおいてもPOODLE攻撃の影響を受けることが確認されています。

Java7のコードでは復号時のTLSのパディング処理がきちんと実装されていることを確認しました。そのため、Java7のサーバはTLSを使っている場合、POODLEで攻撃することはできません。

まとめ

今回は、SSLにまたしても見つかった攻撃手法であるPOODLEについて解説しました。POODLEはもちろんSSLの問題ではありますが、同時にCookieのたった一つの値に依存するウェブアプリケーションのセッション管理方法についても疑問を投げかけるものだと思います。ご意見等あればお気軽に@kinyukaまでお寄せください。