はじめに
― CBC モードに潜む二つの致命的な欠陥 ―
CBC(Cipher Block Chaining)モードは長年使われてきた暗号方式ですが、
「改ざん可能」かつ「認証がない」 という前提のもとでは、まったく性質の違う二種類の攻撃が成立します。
それが:
- Padding Oracle Attack
- Bit Flipping Attack
どちらも CBC を悪用しますが、
目的・条件・結果が完全に違う
という点が理解の分かれ目です。
1. 一発で分かる結論(超重要)
| 観点 | Padding Oracle Attack | Bit Flipping Attack |
|---|---|---|
| 主目的 | 平文を「読む」 | 平文を「書き換える」 |
| Oracle(判定) | 必要(padding OK/NG) | 不要 |
| 復号できるか | ✅ できる | ❌ できない |
| 改ざんできるか | ✅ できる | ✅ できる |
| 必要条件 | padding エラーが漏れる | MAC/署名がない |
| 典型被害 | 機密情報漏洩 | 権限昇格・改ざん |
| 自動化ツール | PadBuster | 自作スクリプト |
「読む攻撃」か「書く攻撃」か
これだけでまず区別できます。
2. 共通の土台:CBC の数式
両方の攻撃は、次の CBC 復号式を悪用します。
$$
P_i = D_k(C_i) \oplus C_{i-1}
$$
ここで重要なのは:
- 攻撃者は 鍵を知らない
- でも $C_{i-1}$ を自由に書き換えられる
つまり:
前のブロックをいじると、次の平文が変わる
この一点が、すべての悲劇の始まりです。
3. Padding Oracle Attack(読む攻撃)
3.1 何をしている攻撃か?
Padding Oracle Attack は:
「padding が正しいか?」という Yes / No を利用して、
平文を 1 バイトずつ復号する攻撃
です。
3.2 成立条件
- CBC モード
- PKCS#7 padding
- padding エラーが外部から判別可能
- ステータスコード
- エラーメッセージ
- レスポンスサイズ
- レスポンス時間
3.3 攻撃の本質
- IV / 前ブロックを 0〜255 で総当たり
- Oracle に投げる
- 「padding OK」が出た瞬間に中間値が確定
- 数式で平文を復元
暗号を解いていないのに、解けてしまう
3.4 典型例
- Cookie 内の session 情報
- 暗号化された JWT 風トークン
- 決済情報
- 個人情報
3.5 代表ツール
- PadBuster
- 独自 Python 実装
4. Bit Flipping Attack(書く攻撃)
4.1 何をしている攻撃か?
Bit Flipping Attack は:
復号結果を“狙った値”に変える攻撃
ただし中身は読めない
という攻撃です。
4.2 成立条件
- CBC モード
- MAC / 署名が存在しない
- 平文の構造がある程度予測できる
padding エラーは 不要
4.3 攻撃の本質(超重要)
CBC では:
$$
P_i = D_k(C_i) \oplus C_{i-1}
$$
なので:
$$
C_{i-1}' = C_{i-1} \oplus \Delta
\Rightarrow
P_i' = P_i \oplus \Delta
$$
XOR 差分を仕込めば、平文も同じ差分で変わる
4.4 超有名な例:権限昇格
元の平文(推測)
role=user;uid=1001
攻撃者の目標
role=admin;uid=1001
やること
-
user→admin - 差分を計算
- 前ブロックに XOR
- サーバーは何事もなく復号して受理
復号結果は改ざんされているが、サーバーは気づかない
5. 両者の決定的な違い
Padding Oracle Attack
- サーバーに質問する攻撃
- 「この padding 合ってる?」
- サーバーが喋りすぎて情報漏洩
- 読む → 書ける
Bit Flipping Attack
- 黙って細工する攻撃
- サーバーは何も教えてくれない
- XOR の性質だけで操作
- 読めない → 書ける
6. ペンテスター視点:どう見分ける?
Padding Oracle が狙える兆候
- padding エラーが見える
- レスポンス差分がある
- CBC + PKCS#7
Bit Flipping が狙える兆候
- 暗号文が改ざん可能
- MAC / 署名がない
- 平文フォーマットが想像できる
7. 開発者視点:両方を一撃で防ぐ方法
答えは一つです。
AEAD を使う
- AES-GCM
- AES-CCM
- ChaCha20-Poly1305
AEAD は:
- 改ざん → 即 reject
- padding oracle → 構造上不可能
- Bit Flipping → 認証で即死
まとめ
-
Padding Oracle Attack:
サーバーが喋るから「読める」 -
Bit Flipping Attack:
XOR が効くから「書ける」 -
AEAD:
両方まとめて消える
「暗号化した」では足りない
「改ざん検出できる暗号化」を使え