【ヒープオーバーフロー】

ヒープオーバーフロー とは?

公開:
💡 隣の部屋まではみ出す荷物、仕切りを壊して大惨事
📌 このページのポイント
ヒープオーバーフローの仕組み 正常な状態 バッファA [64バイト] AAAA... メタデータ バッファB [64バイト] BBBB... 関数 ポインタ オーバーフロー発生! バッファA [64バイト] AAAA... 上書きされた! 悪意あるデータ XXXX... 改ざん された ← バッファの境界を超えて書き込み → 攻撃の流れ 1. バッファAに過大な入力を送信 2. 隣接するBのメタデータを上書き 3. 関数ポインタを攻撃者のコードに変更 4. 任意コード実行を達成 防御策 ✓ 入力サイズの検証を徹底 ✓ ASLR(アドレスランダム化) ✓ ヒープ整合性チェック ✓ メモリ安全な言語(Rust等)を使用
ヒープオーバーフローのイメージ
ひよこ ひよこ
ヒープオーバーフローってバッファオーバーフローとは違うの?
ペンギン先生 ペンギン先生
バッファオーバーフローの一種だよ。バッファオーバーフローにはスタック上で起きるものとヒープ上で起きるものがあって、ヒープ上で起きるのがヒープオーバーフローだね。
ひよこ ひよこ
ヒープで起きると何が違うの?
ペンギン先生 ペンギン先生
スタックオーバーフローは戻りアドレスを書き換えるのが定番だけど、ヒープの場合は隣接するヒープチャンクのメタデータや関数ポインタを書き換えるんだ。倉庫の仕切りを壊して隣の荷物を入れ替えるイメージだよ。
ひよこ ひよこ
具体的にはどうやって攻撃するの?
ペンギン先生 ペンギン先生
たとえばglibcのmalloc実装では、解放済みチャンクが前後のポインタで連結リストを作っているよ。ヒープオーバーフローで隣のチャンクのポインタを書き換えると、次のfree()やmalloc()で任意のアドレスに値を書き込める「unlink攻撃」が成立するんだ。
ひよこ ひよこ
それって防げないの?
ペンギン先生 ペンギン先生
現代のOSやコンパイラには複数の防御策があるよ。ヒープの整合性チェック、ASLR(アドレス配置のランダム化)、ヒープガードページなどだね。glibcも昔のunlink攻撃は対策済みだよ。
ひよこ ひよこ
じゃあもう安全なの?
ペンギン先生 ペンギン先生
いやいや、攻撃者もどんどん手口を進化させているよ。最近はヒープ風水(Heap Feng Shui)といって、アロケーションのパターンを精密に制御してヒープのレイアウトを狙い通りに並べ替えるテクニックが使われているんだ。
ひよこ ひよこ
ヒープ風水って面白い名前だね!プログラマはどう対策すればいいの?
ペンギン先生 ペンギン先生
まず入力サイズの検証を徹底すること。C/C++ではstrncpyやsnprintfなどサイズ制限付きの関数を使うのが基本だよ。さらにAddressSanitizer(ASan)というツールを使うとヒープオーバーフローを実行時に検出できる。根本的にはRustのようなメモリ安全な言語に移行するのが最も確実な対策だね。
ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「ヒープオーバーフロー」って出てきたら「ヒープ領域のバッファからはみ出して隣のデータを壊す脆弱性」と思えればだいたいOK!
📖 おまけ:英語の意味
「Heap Overflow」 = ヒープの溢れ
💬 「heap(ヒープ領域)」が「overflow(あふれる)」という、メモリ破壊の様子がそのまま名前になっているよ
← 用語集にもどる