図  バッファ・オーバーフローの脆弱性を狙った攻撃<BR>悪意あるプログラムと改変したリターン・アドレスを含んだデータによってバッファを溢れさせて,リターン・アドレスを書き換える。リターン・アドレスが読み出されると,悪意あるプログラムが動作する。
図 バッファ・オーバーフローの脆弱性を狙った攻撃<BR>悪意あるプログラムと改変したリターン・アドレスを含んだデータによってバッファを溢れさせて,リターン・アドレスを書き換える。リターン・アドレスが読み出されると,悪意あるプログラムが動作する。
[画像のクリックで拡大表示]

究極の攻撃バッファ・オーバーフロー

 不正なコードを含んだデータをマシンに送りつけて,リモートのマシンを支配下におく—。バッファ・オーバーフローは「魔法の弾丸」と呼ばれるほど,攻撃者にとって魅力的な脆弱性だ。

 一般に外部とデータをやり取りするプログラムは,受け取ったデータを一時的に蓄えておくバッファと呼ぶメモリー領域を持っている。バッファ・オーバーフローはこのバッファの領域を超えてデータが格納される場合に起こる([拡大表示])。

 例えばURLを受け取って,適切なディレクトリのファイルを返すWebサーバーを考える。このとき,バッファにURLを格納し,その構造を解析してどのディレクトリを表しているかを調べる。もし,20文字分しかバッファ領域を確保していないのに,40文字のURLが送られてきたときにどうなるか。もちろん,20文字以内かどうかをチェックするプログラムが構造解析の前にあれば問題は起こらない。

 しかし,チェックを怠ってそのままバッファに収めようとすると,20文字分のデータがバッファの隣のメモリー領域にあふれ出し,元のメモリーの内容を上書きしてしまう。この結果,メモリーの中身が書き換わりプログラマが意図しない動作が引き起こされる。

 バッファのそばには,その処理が終わった後の戻り番地(リターン・アドレス)が書き込まれていることが多い。ここを書き換えられてしまうと,処理が終わったときに,設計者が思ってもみなかったアドレスに飛んでしまう。先のWebサーバーの例で,悪意あるコードと,このコードが書かれた場所を指し示すリターン・アドレスがURLに書かれていたとする。処理が終わったとたん,悪意あるコードが走り出すことになる。

 バッファ・オーバーフローの脆弱性は,主にプログラムがC/C++で書かれている場合に発生する。C/C++の仕様では,メモリーの領域管理はプログラマに任されているからだ。防ぐためには,プログラマが明示的にデータ領域をチェックする必要がある。