SSL暗号を無効化する仕組み – BREACH, CRIME, etc

(Last Updated On: 2018年8月4日)

CRIMEBREACHといったSSL暗号を無効化する攻撃を知っている方は多いと思います。しかし、その仕組みや攻撃方法は広くは理解されていないようです。Webシステムに関わる方であれば、BREACH攻撃の原理と対策を理解しておいて損はありません。BREACHや類似の攻撃は全く難しくありません。直ぐに理解できると思います。原理は簡単です!

CRIMEとBREACH攻撃

CRIMEもBREACHも暗号を解読せずに暗号コンテンツを解読する攻撃です。暗号を直接解読するのではなく、圧縮後のサイズ変化を利用したサイドチャネル攻撃を行います。サイドチャネル攻撃とは攻撃対象のセキュリティ対策(CRIME、BREACHの場合は暗号)などを直接攻撃するのではなく、動作を観察して攻撃する手法です。前回のエントリで紹介したタイミング攻撃では、コンピューターのレスポンス時間を使って攻撃しましたが、CRIMEとBREACHは圧縮後のサイズの違いを使います。

 

なぜ暗号を解読せずに秘密データが分かるのか?

なぜ圧縮が暗号を解読せずに暗号文を解読する為に利用できるのでしょうか?その原理は単純です。圧縮すると、同じデータなら圧縮後のデータは小さいサイズになります。圧縮するデータが異なると圧縮後のサイズが大きくなります。ユーザーがページに表示されるデータを注入できる場合、

ユーザーが挿入したデータ == ページ中の秘密のデータ

となる場合、小さくなります。圧縮後のデータサイズの違いを利用すると、暗号文の中身を少しずつ解析することが可能になります。使う副作用は異なりますが、要領はタイミング攻撃と同じです。

攻撃対象となるページは秘密のデータが含まれ、ユーザー入力がページに反映されるページになります。サイズの変化を知ることができないのでは?と思うかも知れません。攻撃方法は最後に説明します。

 

BREACH攻撃の例

例えば、ログイン後のページにクレジットカード番号が含まれていて、攻撃者はカード番号を盗む事を目的としているとします。ページにはユーザー送信したクエリ文字列が埋め込まれているとします。例えば、クレジットカードのポイントで取得できる商品を検索するページなどで、ユーザーが送信した検索キーワードがページに表示されていて、そのページにクレジットカード番号も表示されている状況を想定しています。数値キーワードは無効な検索キーワードで商品検索は行われない仕様とします。

この場合、ページにはユーザーが送信した「商品検索のキーワード」と秘密であるべき「クレジットカード番号」の両方が表示されています。攻撃者は「商品検索のキーワード」に少しずつクレジットカード番号となる文字を総当り方式でリクエストを送信します。数値キーワードでは検索結果は変わらないので、商品検索のキーワードとクレジットカード番号が一致していると「圧縮後」のデータサイズが小さくなります。小さくなった場合は送信した文字が文書に含まれていることを意味しています。この解析を繰り返せば、組み合わせ全てを推測せずに、少しずつ暗号文の中身を解析できます。

例えば、カード番号を解析するならまず最初の数桁を確定します。最初の桁は会社等に割り振られているので比較的簡単に一致する番号を確定できます。話を簡単にする為、12桁を4桁ずつ解析するとした場合、

9999*3 + 最初の4桁の解析に必要な回数

で解析できます。概ね3万回程度のアクセスでカード番号を盗む事が可能になります。一文字ずつ解析しないのは圧縮後のデータサイズを比較しやすいようにするためです。3桁ずつ解析できるなら

999*4 + 最初の4桁の解析に必要な回数

4千回ほどのアクセスしか必要ありません。2桁ずつ解析できるなら更に少なくなります。

BREACH攻撃でCSRFトークン等が盗まれると解説されています。ここで紹介した方法と同じやり方でCSRFトークンが盗める事が分かると思います。BREACH攻撃例としてCSRFトークンを盗む例が良く紹介されるのは、攻撃対象とできる可能性が高い秘密情報だからです。盗む情報は何でも構いません。

 

BREACH攻撃が可能となる条件

BREACHでページが攻撃可能となるには3つの条件があります。

  • HTTPコンテンツの圧縮が利用されている
  • ユーザーが送信したデータがページに表示される
  • 盗むべきデータがページに表示されている

これらの条件を満たすページがある場合、BREACH攻撃対策が必要です。HTTPコンテンツの圧縮方法は何でも構いません。ストリーム暗号の方が簡単ですが暗号方式は問いません。ブロック暗号でも適切なパディングで埋めればサイズの違いが分かります。

 

BREACH攻撃の対策

BREACH攻撃の対策は以下の通りです。

  • HTTPコンテンツの圧縮を無効化する
  • 秘密データとユーザーデータを分離する(同じページに表示しない)
  • 秘密データをランダムにする(例えば、CSRFトークンに使いきりトークンを利用する。私の本でもお薦めしている方法です。欠点は管理するトークンが多くなりすぎる可能性がある点です。適材適所で使って下さい。)
  • ランダムなデータで秘密データをマスクする(例えば、CSRFトークンにリクエストの度に変わるランダムデータとのXORを利用する)
  • 脆弱なページをCSRFから防御する
  • コンテンツの長さを隠す(ランダムな長さのランダムデータを付け加える)
  • リクエスト数を制限する

攻撃の原理と対策の両方が分かりました。最後にどのように攻撃するかです。

 

BREACHを使った攻撃

攻撃者は自分が管理するルータなどを経由する環境で、被害者を罠ページに誘いそこから被害者のブラウザにリクエストを送信させます。そのパケットを監視して攻撃対象のページサイズをチェックします。SSLを使っていれば攻撃者は攻撃対象ページの中身を知ることはできません。しかしデータサイズを知る事はできます。攻撃者が送らせた多数のリクエストから攻撃者は暗号化されたページの中身を解析し秘密情報を盗むことができます。(MITM攻撃の一種)

BREACH攻撃対策には色々ありますが「CSRFから防御する」が含まれているのは、上記の様な攻撃方法が利用されるからです。「リクエスト数を制限する」のは大量(数千回から数万回)のアクセスが必要となるからです。BREACHでCSRFトークンなどが1分以内に盗まれる、と言われていますが今のWebシステムなら1分間に数千から数万回のリクエストを処理するのは簡単だからです。

SSLは中間者攻撃(MITM)に対して有効とされていましたが、BREACH攻撃に脆弱なページの場合には有効であるとは言えません。SSLで保護されているページで脆弱なページがある場合、対策を行う方が良いでしょう。

攻撃の実験を行うツールも公開されています。

https://github.com/nealharris/BREACH

 

まとめ

対策を行っていないWebページへBREACH攻撃を行うと、ページの中に含まれたCSRFトークンなどが容易に盗める事が分ったと思います。非SSL通信でも同じような解析が可能です。しかし、問題とされないのはMITM環境ではそもそも通信内容が攻撃者に丸見えだからです。

もともとあまりお勧めしていないCSRF対策でしたが、CSRFトークンにセッションIDを使うのは止めましょう。BREACHを使ってCSRFトークンを盗まれてもアカウントの乗っ取りは行えません。しかし、CSRFトークンにセッションIDを利用しているとアカウントを乗っ取られてしまいます。CSRFトークンに対してはXORを使った対策でBREACH対策は行えますが、固定のCSRFトークンではリスクが増えます。適当に新しいCSRFトークンに更新、毎回異なる使いきりトークンを利用すると良いでしょう。

従来は情報を表示するだけのページにCSRF対策は必要ない、とされてきましたがBREACH攻撃を考慮すると情報を表示するだけのページにもCSRF対策が必要になった、とも言えます。CSRF対策だけがBREACH対策ではないので、使いやすい対策を選択すれば良いと思います。

CRIMEはHTTP圧縮ではなくSSL圧縮(SPDY,TLS)を利用する攻撃です。(HTTP圧縮の攻撃も示唆はしていました)HTTPヘッダー、つまりクッキーなどを盗むことが可能でした。現在ではブラウザがSSL圧縮を無効にしているので攻撃できなくなっています。

昨年、一昨年に話題となった問題ですが、参考になれば幸いです。

投稿者: yohgaki