FE EXAM

バッファオーバーフロー(領域あふれ攻撃)

領域を超えるデータを送り込みプログラムを誤動作させる攻撃。

INTERACTIVE VISUALIZATION
バッファ
隣接メモリ
上書き
フェーズ
idle
入力 / 容量
0 / 6
状態
正常
シナリオ
ステップ1 / 6
STEP 1/6バッファ(空の入れ物)プログラムは入力を受け取るために、あらかじめ決まった大きさの入れ物(バッファ)をメモリ上に用意します。ここでは6マス分です。バッファのすぐ隣には、プログラムが次に戻る場所(戻りアドレス)などの大切なデータが置かれています。
バッファ(容量6隣接メモリ······戻り先重要← ここを超えると危険
あふれのしくみ
バッファ容量: 6マス
入力データ: 9マス(容量オーバー)
あふれた3マス → 戻りアドレスを上書き → 制御を奪取
対策: if (入力長 > 容量) 拒否 ← 境界チェック
解説

📌
バッファオーバーフローとは

バッファ隣を破壊容量を超えたデータがあふれて隣を上書き

バッファオーバーフローとは、プログラムが用意した 入れ物(バッファ)の容量を超えるデータを送り込み、あふれた分が隣のメモリを上書きすることでプログラムを誤動作させる攻撃です。「バッファ」は一時的にデータをためる領域、「オーバーフロー」は「あふれること」を意味します。

身近な例で考えると、容量の決まったコップに、限界を超えて水を注ぎ続けるようなものです。水はコップからあふれ、隣に置いてあった大事な書類(重要なデータ)をびしょ濡れにして台無しにしてしまいます。プログラムが「もうこれ以上入らない」と確認しないのが原因です。

上のツールで▶ボタンを押すと、容量内の入力は安全に収まる一方、容量を超える入力が隣のメモリを破壊して制御を奪う流れと、境界チェックで防がれる様子を確認できます。

⚙️
攻撃の仕組み

メモリの中では、バッファのすぐ隣に 戻りアドレス(=処理が終わったあとプログラムが次に戻る場所を示すデータ)などの大切な情報が並んでいます。バッファをあふれさせると、この大切な情報が上書きされてしまう、という点が攻撃の核心です。

攻撃は次の順で進みます。
① あふれ:容量を超える大量のデータを送り込み、バッファからあふれさせる
② 上書き:あふれた分が、隣にある戻りアドレスを塗りつぶす
③ 書き換え:戻りアドレスを「攻撃者が用意したコードの場所」に巧妙に書き換える
④ 乗っ取り:処理を終えたプログラムが攻撃者のコードへ飛び、コンピュータを自由に操られる

単に上書きするだけなら異常終了(誤動作)で済みますが、戻りアドレスを狙って書き換えると任意のコード実行(乗っ取り)という最悪の被害につながります。上のツールのoverwrite〜hijackステップで、隣のメモリが壊れて制御が奪われる様子を見てください。

🛡️
対策

境界を超える分は書き込まない

根本的な対策は境界チェックです。これは データを書き込む前に「バッファの容量を超えていないか」を必ず確かめる処理です。超える分は捨てるかエラーにすれば、隣の大切なデータは決して上書きされません。あふれそうになったら蛇口を止める、というイメージです。

対策は、プログラムの作り方(セキュアプログラミング)とシステムの仕組みの両面から行います。
長さを確認する関数を使う:書き込む長さを指定できる安全な関数を選び、長さチェックのない危険な関数を避ける
入力値検証:受け取るデータの長さに上限を設けてはじく
スタック保護(カナリア):戻りアドレスの手前に見張り役の値を置き、書き換えを検知する
ASLR・DEP:メモリ配置をずらしたり、データ領域のコード実行を禁止して悪用を難しくする

基本は「容量を超えるデータは決して書き込まない」に尽きます。脆弱性が見つかったソフトは速やかに更新(パッチ適用)することも大切です。上のツールの最終ステップで、境界チェックによってあふれが防がれる様子を確認してください。

🔍
なぜメモリの上書きが危険なのか

戻りアドレス0x4000バッファ(4マス)攻撃コードの場所メモリの配置イメージ(横方向が隣のアドレス)バッファの右隣に戻りアドレスが存在する

なぜあふれが「コンピュータの乗っ取り」につながるのか、その仕組みを理解するには「スタック」と「戻りアドレス」というキーワードが重要です。スタック(=関数を呼び出したときに使われる一時的なメモリ領域)には、バッファ(一時入力領域)と戻りアドレス(関数が終わったら次にどこへ戻るかを示す番地)が隣り合わせに置かれています。

住所録カードで例えると、「名前を書く欄」(バッファ)の隣に「次に向かうべき場所のメモ」(戻りアドレス)が書いてある状態です。名前欄に枠を超えて文字を書き続けると、隣のメモが消えて上書きされてしまいます。攻撃者はその「次に向かうべき場所」を自分のコードの場所に書き換えるため、プログラムが攻撃者の指示通りに動いてしまいます。

このことから、バッファオーバーフローは「コンピュータがどこへ戻るかを書き換える」攻撃とも言えます。上のツールのhijackステップで、戻りアドレスが上書きされて制御が移る瞬間を確認してください。

🛡️
対策の比較と仕組み

対策仕組み防ぐのは誰の仕事
境界チェック書き込む前に長さを確認し超えたら拒否プログラマ
スタック保護(カナリア)戻りアドレスの手前に見張り番の値を置き改ざんを検知コンパイラ/OS
ASLRメモリ配置をランダムにして攻撃者がアドレスを推測できなくするOS
DEP/NXデータ領域でのコード実行を禁止するOS/CPU

バッファオーバーフロー対策は「プログラマが書くコードの工夫」と「OSや言語が提供する仕組み」の二段構えで行います。まず根本対策として、プログラマが書き込む前に長さを確認する「境界チェック」を行います。それに加えてスタック保護・ASLR・DEP/NXを組み合わせると、万が一バッファが溢れても被害を最小化できます。

ASLR(アドレス空間配置のランダム化)は「毎回メモリの置き場所を変える」仕組みです。攻撃者が「攻撃コードはアドレス0x8000にある」と書き込んでも、実際の配置が毎回違うため制御を奪うことが格段に難しくなります。DEP/NX(データ実行防止)は「データ領域でプログラムを動かせなくする」仕組みで、スタックに埋め込まれた攻撃コードを実行できなくします。

🔍
バッファとメモリの基本 — なぜ容量を決めるのか

メモリ(プログラムが使う一時保存場所)バッファ(6マス)入力用に確保他のデータ・戻りアドレス別の目的で確保済みユーザーの入力容量を決めるのは「他のデータを守るため」

バッファ(=入れ物)とは、プログラムがデータを一時的に保存するためにメモリ上に確保した領域のことです。プログラムが「名前を入力してください」という欄を用意するとき、「最大20文字分の場所をメモリに取っておく」という処理が必要です。この「取っておいた場所」がバッファです。

なぜ容量(大きさ)を決めるのか:メモリは複数のプログラムや用途で細かく区切って使っています。バッファの隣にはまったく別の目的のデータがびっしり詰まっています。だから「バッファはここからここまで」と境界を決めて、その範囲だけを使うのが原則です。

ところがプログラムが「容量を確認しない」設計だと、入力が容量を超えてもそのまま書き込もうとします。あふれた分は隣のデータ(戻りアドレスなど)を上書きしてしまいます。このことからバッファオーバーフローは「境界を知らないプログラム」と「意地悪に長い入力」の組み合わせで起きる問題だとわかります。対策の第一歩は、書く前に必ず「まだ入る余地があるか」を確認することです。

📋
バッファオーバーフローと他の攻撃の違い

攻撃何を狙うか被害根本対策
バッファオーバーフローメモリの境界プログラム誤動作・乗っ取り境界チェック
SQLインジェクションSQL命令の組み立てDBの不正操作・漏えいプリペアドステートメント
XSSHTML出力の処理クッキー窃取・なりすましエスケープ処理
DoS攻撃サーバの処理能力サービス停止(使えなくなる)レート制限・負荷分散

バッファオーバーフローと他の攻撃を並べると、それぞれ「何が弱点か」が鮮明になります。バッファオーバーフロープログラムのメモリ管理の不備を突く攻撃です。WebアプリのSQL処理やHTMLの出力を狙うSQLインジェクション・XSSとは、問題が起きる場所がまったく異なります。

なぜ区別が大切か:攻撃の種類が違えば対策も違います。たとえばプリペアドステートメントはSQLの問題を解決しますが、メモリの長さ管理には無効です。逆に境界チェックはSQLインジェクションを防げません。問題文で「どの攻撃を選ぶか・どの対策を選ぶか」が問われたとき、攻撃と対策を正しく組み合わせることが重要です。

なお、バッファオーバーフローはWebアプリよりもOSやデバイスドライバ(=ハードウェアをOSが扱うためのプログラム)など、低レベルなプログラムで特に問題になりやすい攻撃です。Web系(SQLi・XSS)との最大の違いは「ネットワーク越しにWebページを操作するのではなく、プログラム自体のメモリを直接壊す」点にあります。

練習問題

🎯
基本情報技術者 練習問題

Q1.バッファオーバーフローの説明として最も適切なものはどれか。
A.確保した領域を超えるデータを送り込み、隣接メモリを破壊してプログラムを誤動作させる攻撃
B.Webページにスクリプトを埋め込み利用者のブラウザで実行させる攻撃
C.入力欄に不正なSQLを注入してデータベースを操作する攻撃
D.DNSに偽の情報を覚え込ませる攻撃
Q2.バッファオーバーフローによってプログラムを乗っ取られる主な理由はどれか。
A.パスワードが暗号化されていないから
B.あふれたデータが戻りアドレスを上書きし、攻撃者のコードへ処理を飛ばせるから
C.通信が暗号化されていないから
D.CPUの動作周波数が高すぎるから
Q3.バッファオーバーフローへの対策として最も適切なものはどれか。
A.書き込む前にバッファの境界(容量)を超えていないかチェックする
B.SQL文をプリペアドステートメントで実行する
C.クッキーにHttpOnly属性を付ける
D.パスに ../ が含まれないか検証する

関連コンテンツ