
このProof of Conceptは、2011年9月23日にThai Duong氏とJuliano Rizzo氏によって発表されたBEAST(Browser Exploit Against SSL/TLS)攻撃の背後にある暗号技術に焦点を当てています。これは選択平文攻撃であり、使用されているTransport Layer SecurityがTLS1.0またはSSLv3の場合に機密情報を取得することができます。 オリジナルのProof of Conceptはこちら: Here come the Ninjas
注記: これは、Phillip Rogaway氏によって最初に発見された脆弱性の実装でもあります。2002年に発見されましたが、2011年にBEASTが登場するまでエクスプロイトは公開されませんでした。OpenSSLはすでにこの問題を認識しており、そのため2006年4月にTLS1.0をTLS1.1に更新しました。
2 最初のレコードを除く各レコードのCBC IVは、前のレコードの最後の 暗号文ブロックである。したがって、この暗号化は、平文を適応的に選択できる攻撃者に対して安全ではない。
SSLv3/TLS1.0は、データを暗号化・復号化し、安全にするためのプロトコルです。今回の場合、どちらもCBC暗号モード(暗号ブロック連鎖)を使用しています。平文は暗号化アルゴリズム(AES、DES、3DES)に応じてブロックに分割され、その長さは8または16の倍数になります。平文がその長さに満たない場合は、不足分を埋めるために最後にパディングが追加されます。このREADMEを読む際には、暗号化と復号化の図を開くことを強くお勧めします。
| 暗号化 | 復号化 |
|---|---|
| Ci = Ek(Pi ⊕ Ci-1), and C0 = IV | Pi = Dk(Ci) ⊕ Ci-1, and C0 = IV |
基本的には単純なXORに過ぎません。このビデオ(私のものではありません)も見ることができます: https://www.youtube.com/watch?v=0D7OwYp6ZEc
IVについては次の項目で紹介します。これらの特性がすべて攻撃を進めるのに役立つことを覚えておいてください。
CBCを使用する場合、IVと呼ばれる初期化ベクトルが必要です。このIVはランダム(または固定)ですが、いずれにしても誰にも予測できないものでなければなりません。TLS1.0とSSLv3では、リクエストの最初のIVはランダムです。それは問題ありません。しかし、毎回新しいランダムなIVを生成する時間を省くため、TLS1.0とSSLv3の実装では、前の暗号文の最後のブロックをIVとして使用していました。言い換えれば、IVは推測可能になったのです。 各ブロックの長さは8(DES)であり、攻撃者はすべての暗号文を取得するためにMiTM(中間者)を使用すると仮定します。
例:
C0 | C... | Ci-1 | Ci | Ci+1 |Cn
ここからが面白い部分です。1バイトを取得するための攻撃の暗号化手順は次のとおりです。
bbbbbbbTHIS_IS_A_SECRET_COOKIE を被害者経由で送信できます。シークレットクッキーの前にある7つの b に気づくでしょう。ブロックの長さが8の場合、既知の7バイトを押し込む必要があります。この情報は非常に重要です。攻撃者は最初のブロックの最初の7バイトを知っていることになります。
なぜでしょうか? これにより、8バイトを見つけるための256^8ではなく、1バイトを見つけるための256通りの可能性だけで済むからです!
次に、被害者がリクエストを送信すると、次のように暗号化されます:
C0 | C1 | C2 | C3 | C4
ここで C0 = Ek(IV ⊕ bbbbbbbT) = Ek(C²n ⊕ bbbbbbbT) です。
P'0 = C²n ⊕ C4 ⊕ bbbbbbbX
唯一不明な要素は X です。256通りの可能性があるため、最大256文字を試すことになります。
リクエストが送信され、次のように暗号化されます:
C'0 = Ek(P'0 ⊕ IV')
C'0 = Ek(C²n ⊕ C4 ⊕ bbbbbbbX ⊕ IV') または C4 ⊕ IV' = 0
C'0 = Ek(C²n ⊕ bbbbbbbX)
C'0 = Ek(IV ⊕ bbbbbbbX)
次に、C'0 と C0 を比較します。それらが等しければ、位置8のバイト X が見つかったことになります。一致しない場合は、別の文字で再試行して再度比較します。
1バイトが得られれば、前のリクエストを左に1つずらすことで別のバイトも取得できます: bbbbbbTHIS_IS_A_SECRET_COOKIE。これで b が6つになり、T も分かっているので、不明な文字は1つだけになります。新しい P'0 = C0 ⊕ C4 ⊕ bbbbbbTX を構築します。
注記: わずか2つのリクエストで行う別の方法は、平文の最初のブロックを設定し、その情報を3つのXORに使用することです。C²の最後のブロックはもう必要ありません。C1 = Ek(C0 ⊕ bbbbbbbT) とし、その後 P'0 = C0 ⊕ C4 ⊕ bbbbbbbX とします。また、C'0 と C1 を比較する必要があります。 これは別の方法です。PoCでは、2つの可能性の両方をコード化していることに気づくでしょう :)
これで、すべての文字を取得できます!
python BEAST-poc.py
攻撃者はHTTPプロトコルを使用できません。最初のブロックが GET / HTTP/1.1\r\n で埋められてしまうからです。
... 各リクエストの最初の数バイトは、GET /、POST / などの固定文字列として常に設定されるため、制御できません。 代わりにソケットを使用できます。
また、攻撃者は悪意のあるページにJavaScriptを注入する必要があります。被害者はこのページに接続し、攻撃が完了するまでそのページに留まる必要があります。 これは選択平文攻撃であるため、攻撃者はJavaScriptコードを通じて任意の平文を送信し、その結果を中間者(Man in The Middle)で傍受できます。これが攻撃の図です:

この攻撃を成功させるには重要な条件が必要です(TLS1.0以下、CBC暗号モード、MiTM、悪意のあるJavaScript)。しかしThai Duong氏とJuliano Rizzo氏はそれが可能であることを証明し、PaypalのWebサイトでCookieを盗むことによってそのエクスプロイトを実演しました。
現在はすべて修正されており、この攻撃が実際に実行される可能性はほとんどありません。