【CTF上級編|第4話/全10話】パディングオラクル攻撃|「復号成功/失敗」だけで暗号文を解く

⚡ CTF上級編|第4話/全10話

パディングオラクル攻撃|「復号成功/失敗」だけで暗号文を解く

第3話まで&#x306FWebアプリの「信頼境界」の崩れを見てきました。第4話は暗号そのものに切り込みます。CBCモードの暗号文は、鍵を一度も知らなくても、「復号が成功したか失敗したか」というたっ&#x305F1ビットの情報が漏れるだけで、平文を1バイトずつ完全に解読できてしまいます。この事実を、本物&#x306EWeb Crypto APIを使って体験します。

🔓 パディングオラクル攻撃 🧮 AES-CBCモードの構造的弱点 🔬 本物&#x306EWeb Crypto APIで検証 ⭐ 難易度:★★★★★
01

🔓 パディングオラクル攻撃とは|「成功/失敗」だけで解読する

鍵を知らなくても、平文を完全に復元できる

💭

1ビットの情報だけで全文が判る

パディングオラクル攻撃(Padding Oracle Attack)は、CBC(Cipher Block Chaining)モードで暗号化されたデータを、鍵を一度も知ることなく完全に復元できてしまう、暗号学の中でも特に有名な攻撃手法の1つです。2014年のPOODLE、2013年&#x306ELucky13といった名前のついた深刻な脆弱性も、この攻撃手法の一対です。

攻撃者は暗号文を少しだけ改ざんしてサーバーに送ります。サーバーはそれを復号しようとし、「パディング(暗号化時に追加される埋め淨のバイト極)」が正しい形式かどうかを検査します。この検査結果(成功か失敗か)が何らかの方法で攻撃者に伝わってしまうと、攻撃者は改ざんを何度も繰り返しながら、平文𰤢󿆁バイトずつ確定させていきます。

パディングオラクル攻撃のループ 攻撃者 改ざんした暗号文 サーバー(オラクル) 復号+パディング検査 成功 or 失敗(1ビット) 最大256×16×ブロック数回 繰り返して平文を1バイトずつ確定 鍵を一度も知らなくても、平文を完全に復元できてしまう
📌

この話の前提知識

実践編第6話で学んだ「暗号モードの構造的な弱点」という発想をさらに深めます。ECBは「暗号文の見た目のパターン」が漏れる弱点でしたが、今回&#x306FCBCの「復号の成功/失敗」が漏れる弱点です。

  • 実践編 第6話「ECBモードの弱点を見抑く|暗号文に浮かぶパターン」
02

🧮 CBCモードの仕組み|なぜパディングが手がかりになるのか

前のブロックを操れば次の復号結果を操れる

CBC(Cipher Block Chaining)モードでは、あるブロックCₙの復号は「Dₖ(Cₙ) XOR Cₙ₋₁」(1個前の暗号文ブロックとXOR)で求まります。注目すべきのは、前のブロックCₙ₋₁を书き書きすれば、復号結果もそのま&#x307EXORされて変わるという点です。鍵Dₖを知らなくても、前のブロックを操れば復号結果を自在に操作できてしまいます。

暗号化前のデータ&#x306F16バイトの倍数でなければならないため、PKCS7という方式で末尾にパディングを埋めます。埋めるバイト数と同じ値を、その数だけ並べるのが特徴です。

元のデータ長必要なパディング末尾のバイト列(16ブロック中)
15バイト1バイト… 01
14バイト2バイト… 02 02
9バイト7バイト… 07 07 07 07 07 07 07
16バイト(ちょうど1ブロック)16バイト(丸々と1ブロック追加)10 10 10 …&#xFF0816個)
🎯

攻撃の核心:中間値を1バイトずつ確定する

末尾バイトを0~255まで全探索し、パディングが有効になる値を1つ見つけると、そ&#x306EXOR関係から&#x300CDₖ(Cₙ)の末尾バイト」(中間値)がわかります。それを本当の前のブロッ&#x30AFCₙ₋₁とXORすれば、本当の平文の末尾バイトが手に入ります。次は「末尾&#x304C02 02になる」ように既知の最後のバイトを固定しながら、その1つ手前を同じように全探索します。これをブロックの先頭まで繰り返せば、ブロック全体の平文が判明します。

03

👁️ オラクルの正体|エラーメッセー𰮂の違いが命取りになる

「パディングが不正です」とは一言も表示しなくても、オラクルになる

「オラクル」と呼ばれる側は、「パディングエラー」と直接表示する必要は一切ありません。サーバーの振る舞いに、パディングが有効か無効かで区別できる何か一つでも差があれば、それだけで極成り立ちます。例えばパディングが不正なときはHTTP 500エーラー、パディングが正しく(中身の値自体は意味がなくても)判定処理に進め&#x305FHTTP 200(「ユーザーが見つかりません」等)、というただそれだけの違いでも充分にオラクルとして機能してしまいます。第2話で学んだSSRFの「小さな実装の雗」と同じ発想です。

⏱️

メッセージさえ同じでも成立する&#xFF1ALucky13のタイミング攻撃

2013年に発見され&#x305FLucky13は、エラーメッセージを完全に統一していても成立するさらに高度なパディングオラクルです。パディングが正しい場合はその後&#x306BHMAC検証処理も走るため、不正な場合と比べて処理時間がわずかに長くなります。この数ミリ秒単位の応答時間差だけを手がかりに、エラーメッセージを完全に統一していても同じ攻撃が成立しました。

04

🔎 実践チャレンジ:オラクルを見抑き、暗号文を解読せよ

本物&#x306EAES-CBC(Web Crypto API)を使ったラボ

架空の「やさい人事システム」には、AES-CBCで暗号化された「プロフィールトークン」を復号する機能があります。下の3つのサンプルを送信して、サーバー(のふり)の応答の違いを確認してください。この3つはすべて、本物&#x306EWeb Crypto APIで実際に復号を試行しています。

上のボタンを押して、応答の違いを確認してください。
🧩 実践チャレンジ:2つのステージで暗号文を解読せ

ステー&#x30B81をクリアすると、ステー&#x30B82が解放されます。両方クリアした時点でスコアが確定します。

📊 ステージ進捗: 0/2|挑戰回数: 0回

1ステー&#x30B81:オラクルの挑動を見極める

3つのサンプルのうち、「パディングが有効(200 OK相当)」と判定された番号をPADDING-OK-〇形式で入力してください(例:PADDING-OK-1)。

第4話の攻撃チェーン ステー&#x30B81:オラクル見極め 200 vs 500で区別 ステー&#x30B82:自動攻撃 256×16×ブロック数回 平文復元 鍵不要+CTF符号 1ビットのオラクル+繰り返し=鍵不要の完全復号
05

🛡️ 防御側の視点|パディングオラクル攻撃をどう防ぐか

根本対策は「パディングの有無で振る舞いを分けない」こと

  • AEADモードを使う:AES-GCMなどのAEAD(Authenticated Encryption with Associated Data)モードは、暗号文の改ざんを認証タグで即座に検知し、そもそもパディングという概念を使わないため、パディングオラクル自体が成立しません。現在の実装では最一の選択とされています。
  • Encrypt-then-MAC:CBCをどうしても使う必要がある場合は、復号を試みる前&#x306BHMACで暗号文の改ざんを先に検証し、改ざんがあればその時点で拒否する(パディング検査にたどり付かない)
  • 一定の応答を返す:パディングエラーとその他のエラーで応答(ステータスコード・エーラー文文面)を完全に一定にする
  • 処理時間を一定にする:Lucky13対策として、検証処理の所要時間が成功/失敗で差がでないように実装する(定数時間比較)

今日新規に実装するなら、CBCは選ばない

TLS1.3や最新の暗号化APIの仕様は、CBCモードを事実上廃止し、AES-GCMやChaCha20-Poly1305など&#x306EAEADモードに一本化しています。今から新しく暗号化を実装するなら、CBCを選ぶ理由はほとんどありません。

06

📝 まとめ+FAQ+次回予告

鍵不要で暗号文を解き切った

第4話では、本物&#x306EAES-CBCを使って、鍵を一度も知らないまま暗号文を完全に復号しました。次回はレースコンディションという、チェックと実行の間に生まれる「時間の雕間」をつくタイミング攻撃を扱います。

✅ 今回のまとめチェック

・CBCモードの復号は「成功/失敗」の1ビットだけで平文を完全に割り出せる
・前のブロック(IV含む)を操作し、パディングが有効になる値を1バイトずつ探す
・オラクルは「パディングエラー」と明言しなくても、応答の違い(エラーコードや文面、時間)だけでも成立する
・最強の防御はAES-GCM等&#x306EAEADモードに切り替えること

Q. 現在、実際のWebサービスでもパディングオラクル攻撃は通用しますか?

TLS(HTTPS)の文脈で&#x306FTLS1.3でCBCモードが完全に廘止されたため大幅に減っています。しかしクーキーの暗号化や自作の暗号通信プロトコルなど、CBCモードを自前実装している箇所では今でも発見されることがあります。

Q. オラクルの応答が1回しか取れない場合(リクエスト数制限等)、この攻撃は防げますか?

遵延しますが防ぐとは限りません。1ブロック(16バイト)を復号するには最&#x59271×16×256回(最&#x59273840回)の問い合わせで十分なため、単位時間あたりのオラクル呼び出し数を制限すれば攻撃時間を大幅に伸ばせますが、根本対策にはならないとされています。

Q. 自分で鍵を持っていれば、もっと早く復号できるのになぜこんな手間な方法を使うのですか?

この攻撃の価値はまさに「鍵を持たない攻撃者でも、サーバーの振る舞いの違いだけで平文を得られる」という点にあります。実際の攻撃者も鍵を持っていない前提でこの手法を使います。

Q. 暗号文やIVの値はどこかに送信されますか?

送信されません。すべてブラウザ&#x306ElocalStorage(あなたの端末内)だけに保存され、外部のサーバーには一切送信されません。

次回.第5話

レースココンディション|タイミーグトのずれを突く同時リクエスト攻撃

チェックと実行の間に生まれる時間の雕間を突き、同一価値を二重に利用する不正を体験します。

📚 参考情報

  • &#x300CCTF上級編」実践編第6話(ECBモード)
  • OWASP Top 10(A02:2021 Cryptographic Failures)

コメント