バッファオーバーフロー(英: buffer overflow)またはバッファオーバーラン(英: buffer overrun)は、コンピュータのプログラムにおけるバグのひとつ、またはそれにより引き起こされる現象で、プログラムがバッファに割り当てられた空間よりも大きなデータを書き込むことで、データがバッファ境界からあふれ、バッファの範囲外のメモリを上書きし、元々そのメモリにあったデータを破壊してしまうことを指す。
バッファオーバーフローは、上書きされるメモリ領域がスタック領域なのかヒープ領域なのかに応じてそれぞれスタックベースのバッファオーバーフロー、ヒープベースのバッファオーバーフローと呼ばれる。なお、名称が似ているスタックオーバーフローとは別の現象である。
サイバーセキュリティ・情報セキュリティの分野では、バッファオーバーフローはメモリ破壊系の脆弱性の一つとして知られ[1]、攻撃者がバッファオーバーフロー脆弱性のあるプログラムに意図的に悪意のあるデータ(コード)を与えることにより、コンピュータの制御を乗っ取ってしまうことを可能にする。バッファオーバーフロー脆弱性を悪用した攻撃をバッファオーバーフロー攻撃という[2]。 以下の例では、プログラム中の隣接したアドレスに2つのデータ項目が定義されている。一つは 8 バイトの文字列バッファ A、もう一つは 2 バイトの整数 B である。初期状態では、A は 0 で初期化されており可読な文字は入っていない。また、B には整数 1,979 が格納されている。文字のバイト幅は 1 バイトとする。また、エンディアンはビッグエンディアンとする。 変数名AB ここで、プログラムがバッファ A にヌル終端文字列「excessive」を書きこもうとした場合を考える。文字列の長さチェックが行われていないと、この処理で B の値が上書きされてしまう。 変数名AB プログラマとしては B を変更する意図はなかったが、B の値は文字列の一部で置き換えられてしまった。この例ではビッグエンディアンとASCIIコードを仮定しているため、文字「e」とゼロというバイト列は整数 25,856 として解釈される。ここで、仮にプログラム中で A と B 以外にデータ項目変数が定義されていないとものすると、さらに長い文字列を書き込んで B の終端を超えた場合にはセグメンテーション違反などのエラーが発生してプロセスが終了する。 コンピュータプログラムを作るとき、固定長のバッファとよばれる領域を確保してそこにデータを保存するという手法がよく使われる。 たとえば、電子メールアドレスは200文字を超えないだろうと予想して これがバッファオーバーフローである。仮にはみ出した部分にプログラムの動作上意味を持つデータがあれば、これを上書きして破壊することにより、プログラムはユーザの意図しない挙動を示すであろう。 このようにバッファオーバーフローは、プログラムが用意したバッファの大きさを超えてデータを書き込んでしまうバグである。 C言語の標準入出力関数であるgets関数はバッファ長のチェックを行わないで標準入力をバッファに書き込むので、この関数を使う全てのプログラムには、バッファオーバーフローによる不正動作の危険性がある。また使い方が分かりやすいという理由でC言語初心者向けの入門プログラミングでしばしば用いられるscanf関数も書式指定を誤った場合は同じ危険性を持っている[3]。これらの関数を実用的なプログラムで用いる場合には注意が必要である。 次のプログラムはgets関数を用いた例である(セキュリティ上、gets関数はそれ自体をテストする以外の目的で使用されるべきではない。Linux Programmer's Manualには「gets()は絶対に使用してはならない」と書かれている)。バッファ長として200バイト確保されている。gets関数はバッファの長さについては関知しないため、200バイトを超えても改行文字かEOFが現れなければバッファオーバーフローが発生する。#include <stdio.h>int main(int argc, char *argv[]){ char buf[200]; gets(buf); ....} gets関数の代わりにfgets関数を用いることで、この問題を回避できる(fgets#getsを置き換える例等を参照)。fgets関数にはバッファのサイズを渡すことができ、このバイト数を超えてバッファに書き込みを行わない。したがってバッファサイズが正しく設定されていれば、fgets関数においてバッファオーバーフローは起こり得ない。 これ以外のC言語の標準文字列処理関数の多くにも同様の問題(脆弱性)がある。 情報セキュリティ・サイバーセキュリティにおいてバッファオーバーフロー攻撃は、バッファオーバーフローの脆弱性を利用した攻撃である。バッファオーバーフローの脆弱性は整数オーバーフロー、書式文字列バグ、Use-After-Free 共通脆弱性タイプCWEには、 番号名称 などが登録されており、これら3つはいずれも「CWE-119: メモリバッファの境界内における操作の不適切な制限」[7]に属している[7][8]。
バッファオーバーフローの具体例
簡単な例
値NULNULNULNULNULNULNULNUL1979
16進数値000000000000000007BB
値「e」「x」「c」「e」「s」「s」「i」「v」25856
16進数値65786365737369766500
電子メールアドレスを題材にした例
200文字分の領域をバッファとして用意する。
ユーザが200文字より長いメールアドレスを入力する。
プログラムがバッファの大きさをチェックせずに入力データを書き込む。
バッファとして確保した領域をはみだしてデータが書き込まれてしまう。
C言語特有の例
バッファオーバーフロー攻撃
CWE-120入力サイズをチェックしないバッファのコピー(古典的バッファオーバーフロー)[4]
CWE-121スタックベースのバッファオーバーフロー[5]
CWE-122ヒープベースのバッファオーバーフロー[6]
Size:135 KB
出典: フリー百科事典『ウィキペディア(Wikipedia)』
担当:undef