概要
バッファオーバーフロー(BOF:Buffer Overflow)は、プログラムが確保したバッファの範囲を超えてデータを書き込むことで、隣接するメモリ領域を上書きする脆弱性です。攻撃者が戻りアドレスを書き換えることで任意コード実行(RCE)が可能になります。C/C++など手動メモリ管理言語で特に問題となり、SC試験の午前Iでは定番の出題テーマです。
仕組みと動作原理
スタックバッファオーバーフロー
スタックには関数の局所変数・引数・戻りアドレスが積まれています。
スタックの配置(低アドレス → 高アドレス):
[バッファ(8バイト確保)] [その他変数] [SFP] [リターンアドレス]
通常の入力("ABCD"):
[A][B][C][D][ ][ ][ ][ ] [SFP] [正常なリターンアドレス]
悪意ある入力(20バイト):
[A]...[A][A][A][A] [A][A][A][A] [攻撃者のアドレス]
バッファ溢れ SFP上書き リターンアドレス上書き
リターンアドレスを書き換えることで、関数の返り先を攻撃者のコード(シェルコード)に誘導できます。
ヒープバッファオーバーフロー
動的メモリ(malloc/new で確保)の範囲を超えた書き込みです。ヒープ管理構造を破壊し、任意コード実行に至るケースがあります。Use-After-Free(解放済みメモリへのアクセス)も関連した脆弱性です。
整数オーバーフロー
整数型の最大値を超えた計算結果がラップアラウンド(折り返し)することで、バッファサイズ計算が誤り、BOFが発生するケースがあります。
主な防御技術
OSレベルの防御
| 技術 | 仕組み | 効果 |
|---|---|---|
| ASLR(Address Space Layout Randomization) | スタック・ヒープ・ライブラリのアドレスをランダム化 | リターンアドレスの予測を困難にする |
| DEP/NX(Data Execution Prevention / No eXecute) | データ領域のコード実行を禁止 | スタック上のシェルコード実行を防止 |
| Stack Canary | 関数呼び出し時にリターンアドレス直前に乱数(カナリア値)を配置。関数返り時に値が変わっていたらBOFを検出 | リターンアドレス書き換えを検出 |
| CFI(Control Flow Integrity) | 関数の呼び出し先を正規のアドレスに制限 | ROP攻撃を緩和 |
コードレベルの防御
| 技術 | 説明 |
|---|---|
| 境界チェック | gets() → fgets() など境界チェックありの関数を使用 |
| メモリ安全言語の採用 | Rust・Go・Javaなど境界チェックを自動で行う言語を使用 |
| 静的解析(SAST) | コンパイル前にBOFパターンを検出するツールを使用 |
| ファジング | 大量のランダム入力でBOFを発見するテスト手法 |
高度な攻撃技法(ASLRとDEP回避)
| 技法 | 仕組み |
|---|---|
| ROP(Return-Oriented Programming) | DEPがあってもすでにメモリ上の正規コード断片(ガジェット)を繋いで任意処理を実行 |
| Heap Spray | 大量のメモリにシェルコードを配置してASLRを確率的に回避 |
| Ret2libc | libc の system() 関数を呼び出してシェルを起動 |
メモリ安全性の現代的な議論
2023年にNSA・CISAが「メモリ安全言語(Rust・C#・Java・Go等)へ移行すること」を推奨するガイダンスを発表しました。Microsoftのセキュリティ脆弱性の約70%はメモリ安全性の問題に起因するとされています。
SC試験での頻出ポイント
- スタックBOFの原理:バッファを溢れさせてリターンアドレスを上書きし、任意コードを実行
- ASLRの目的:メモリアドレスをランダム化して攻撃コードのアドレス予測を困難にする
- DEP/NXの目的:データ領域のコード実行を禁止してスタック上のシェルコード実行を防ぐ
- カナリア値の役割:リターンアドレス手前に置いてBOFを検出する番人(canary=炭鉱のカナリア)
- ROP攻撃とは:DEPを回避するためにすでにメモリ上の正規コード断片を連鎖的に実行する高度な攻撃
よくある誤問・ひっかけパターン
誤り① 「ASLRだけでBOFは防げる」→ 誤。ASLRはアドレス予測を困難にするだけで、BOF自体を防ぎません。Heap Sprayなどで回避されることもあります。
誤り② 「Java・Pythonではバッファオーバーフローは発生しない」→ 基本的に正しい。ただしJVMやインタープリタ自体がC/C++で書かれているため、そこに脆弱性があれば影響を受ける可能性があります。
誤り③ 「DEPを有効にすればROP攻撃を防げる」→ 誤。ROP攻撃はDEPを前提として考案された回避技法であり、DEPだけでは防げません。
関連用語
- セキュアコーディング — BOF防止のためのコーディング規約
- マルウェア・ランサムウェア — BOFを利用した初期侵入手法
重要キーワード
| 用語 | 説明 |
|---|---|
| バッファオーバーフロー | バッファの境界を超えたデータ書き込みによる隣接メモリの上書き |
| リターンアドレス | 関数の処理が終わった後に実行を再開するアドレス |
| ASLR | スタック・ヒープ・ライブラリのメモリアドレスをランダム化する防御技術 |
| DEP/NX | データ領域でのコード実行を禁止するCPU・OS機能 |
| Stack Canary | 関数返り時にリターンアドレス改ざんを検出するためのランダム値 |
| ROP | 既存コード断片を繋いでDEPを回避する高度な攻撃技法 |