バッファオーバーフロー

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



バッファオーバーフロー(またはバッファオーバーラン)は、コンピュータプログラムにおける深刻なバグの一つです。これは、プログラムがデータ格納のために確保したメモリ領域(バッファ)を超えてデータを書き込もうとする際に発生します。この結果、バッファの境界を越えたデータが隣接するメモリ領域を上書きし、本来そこに存在していたデータを破壊したり、プログラムの動作を異常にしたりします。

バッファオーバーフローは、上書きされるメモリ領域がスタック領域かヒープ領域かによって、それぞれスタックベースのバッファオーバーフロー、ヒープベースのバッファオーバーフローと呼ばれます。ただし、スタックオーバーフローとは異なる現象です。

バッファオーバーフローの危険性



サイバーセキュリティの観点から見ると、バッファオーバーフローはメモリ破壊系の脆弱性として非常に危険です。攻撃者はこの脆弱性を悪用し、プログラムに悪意のあるデータ(コード)を送り込むことで、コンピュータを乗っ取り、自由に操作することが可能になります。このような攻撃をバッファオーバーフロー攻撃と呼びます。

具体例



簡単な例


プログラム内で、連続したメモリ領域にデータA(8バイトの文字列バッファ)とデータB(2バイトの整数)が定義されているとします。初期状態では、Aは空で、Bには1979が格納されています。ここで、プログラムがAに文字列「excessive」を書き込もうとすると、長さのチェックが行われていない場合、文字列がBの領域を上書きしてしまいます。その結果、Bの値が意図せず変更されてしまいます。

電子メールアドレスの例


プログラムが電子メールアドレスを保存する際に、200文字分のバッファを用意したとします。もしユーザーが200文字を超えるメールアドレスを入力した場合、プログラムがバッファの大きさを確認せずにデータを書き込むと、バッファオーバーフローが発生します。この時、はみ出した部分がプログラムの重要なデータを上書きしてしまうと、プログラムは予期せぬ動作をすることになります。

C言語における例


C言語のgets関数は、バッファの長さチェックを行わずに標準入力をバッファに書き込むため、バッファオーバーフローが発生しやすいことで知られています。また、scanf関数も、書式指定を誤ると同様の危険性があります。これらの関数は、実用的なプログラムで使用する際には注意が必要です。

バッファオーバーフロー攻撃



バッファオーバーフロー攻撃は、この脆弱性を利用した攻撃で、メモリ破壊系の脆弱性の一つです。

CWE(Common Weakness Enumeration)では、以下の種類が登録されています。

CWE-119: メモリバッファの境界内における操作の不適切な制限
CWE-120: バッファの境界外へのコピー
CWE-122: ヒープベースのバッファオーバーフロー

これらの脆弱性は、主にC言語C++で発生しやすいですが、古典的なバッファオーバーフローはアセンブリ言語でも起こり得ます。

古典的なバッファオーバーフロー



バッファAのデータをバッファBにコピーする際、BのサイズがAより小さい場合に発生します。プログラマーがサイズチェックを怠ると、この脆弱性が生まれます。攻撃者は大きな入力を与えることで、このオーバーフローを誘発できます。

スタックベースのバッファオーバーフロー攻撃



スタック領域に割り当てられたバッファが上書きされることで発生します。攻撃者は、文字列の長さを調整し、リターンアドレスを悪意のあるコードのアドレスに書き換えることで、プログラムの実行を乗っ取ります。

スタックの構造


スタックは関数呼び出しの際に使用されるメモリ領域で、各関数のデータ(スタックフレーム)が順番に格納されます。スタックフレームには、ローカル変数、関数の引数、戻りアドレスなどが含まれます。

攻撃の仕組み


攻撃者は、バッファに過剰なデータを書き込むことで、リターンアドレスを上書きし、プログラムの実行を乗っ取ります。具体的な手順は以下の通りです。

1. シェルコード(悪意のあるコード)をバッファに書き込む
2. リターンアドレスをシェルコードのアドレスに書き換える
3. 関数が終了する際に、シェルコードが実行される

NOPスレッド


攻撃を成功させるために、リターンアドレスを正確に特定する必要はありません。NOP(No Operation)命令を連続して並べたNOPスレッドを使用することで、リターンアドレスの誤差を吸収し、攻撃を成功させやすくできます。

戻りアドレスの予想


攻撃者は、スタック領域のアドレスを完全に知らなくても、相対アドレスを利用して攻撃が可能です。

コード量が小さい場合の対処


攻撃コードがバッファに収まらない場合、環境変数に攻撃コードを仕込むなどの手法が用いられます。

ヒープスプレー


ヒープ領域に攻撃コードを配置する手法です。JavaScriptなどでヒープを操作し、攻撃コードを配置します。

トランポリング


レジスタに格納されたアドレスを利用して、攻撃者のデータにジャンプする手法です。

ヒープベースのバッファオーバーフロー



mallocなどで動的に確保されたヒープ領域に対する攻撃です。ヒープ上のメタデータを書き換えることで、メモリ管理を不正に操作し、任意のコードを実行させます。

mallocのメモリ管理


mallocは、メモリプールをchunk単位で管理しています。chunkには次のchunkや前のchunkへのポインタが含まれており、これらを書き換えることで、メモリ管理を不正に操作します。

mallocのメタデータの書き換え


ヒープオーバーフローによって、chunkのメタデータを書き換えることで、任意のメモリアドレスに任意のデータを書き込むことができます。

バッファオーバーフローの結果



write-what-where状態



任意の場所に任意の値を書き込める状態になり、セキュリティポリシー外のメモリを操作できます。

プログラムのフリーズ・クラッシュ



意図的にオーバーフローを発生させ、プログラムをクラッシュさせたり、無限ループに陥らせたりします。

関数ポインタの書き換え



関数ポインタを書き換えて、プログラムの実行を乗っ取ります。

バッファオーバーフローの対策



コンパイラやライブラリによる対策



カナリア: ローカル変数とSFPの間にカナリアと呼ばれる値を挿入し、バッファオーバーフローを検知します。
StackGuard: Microsoft Visual C++のGSオプションで、カナリアによる対策を行います。
安全なライブラリへの置き換え: 標準Cライブラリの危険な関数を、より安全な関数に置き換えます。

実行環境での対策



Write XOR eXecute (W^X): データ領域でのコード実行を禁止します。WindowsではDEP(データ実行防止)と呼ばれます。
ASLR (Address Space Layout Randomization): アドレス空間の配置をランダム化し、攻撃を困難にします。カーネル空間でのASLRはKASLRと呼ばれます。

開発時の対策



プログラミング言語の選択: バッファオーバーフローが発生しにくい言語を選択します。
ソースコード記述時の対策: データ長とバッファ長のチェックを徹底します。
安全なライブラリの使用: バッファオーバーフローを防ぐためのセキュアなライブラリを使用します。
静的コード解析: 人手または自動ツールで、バッファオーバーフローの脆弱性がないかを確認します。

発展的な攻撃



Return-to-libc攻撃: W^Xを回避するため、標準ライブラリの関数を利用して攻撃します。
Return-to-Register攻撃: レジスタが指すアドレスに悪意のあるコードを実行させる攻撃です。
ret2esp攻撃: スタックポインタ(esp)を操作して攻撃します。

歴史



バッファオーバーフローの概念は1972年には文書化されていましたが、1988年のMorris worm事件で初めて悪用されました。その後、1996年にはAleph Oneによる記事が公開され、バッファオーバーフロー攻撃の詳細が広く知られるようになりました。Code RedやSQL Slammerなどのワームもバッファオーバーフローを利用しています。

参考文献



八木毅; 村山純一; 秋山満昭 (2015-03-17). コンピュータネットワークセキュリティ. コロナ社. ISBN 978-4339024951
Erickson, Jon 村上雅章訳 (2011-10-22). Hacking: 美しき策謀 第2版 ―脆弱性攻撃の理論と実際. オライリージャパン. ISBN 978-4873115146
“セキュア・プログラミング講座 C/C++言語編”. 情報処理推進機構. 2018年12月14日閲覧。
“CTFで学ぶ脆弱性(スタックバッファオーバーフロー編・その1)”. NTTデータ先端技術株式会社. 2018年12月14日閲覧。
Heap Exploitation Modern Binary Exploitation CSCI 4968 - Spring 2015
2013-12-27 Monthly Research 「Heap Exploitのこれまでと現状」 FFRI. 2018年12月26日閲覧。
メモリ破損脆弱性に対する攻撃の調査と分類
Discovering and exploiting a remote buffer overflow vulnerability in an FTP server
Smashing the Stack for Fun and Profit
An Overview and Example of the Buffer-Overflow Exploit
CERT Secure Coding Standards
CERT Secure Coding Initiative
Secure Coding in C and C++
SANS: inside the buffer overflow attack
Advances in adjacent memory overflows
A Comparison of Buffer Overflow Prevention Implementations and Weaknesses
More Security Whitepapers about Buffer Overflows
Writing Exploits III from Sockets, Shellcode, Porting & Coding
Computer Security Technology Planning Study (1972)

関連項目



Phrack
Exec Shield
バッファアンダーラン
Billion laughs
Computer insecurity
End Of File
書式文字列攻撃
ヒープオーバーフロー
Ping of death
ポートスキャン
Security focused operating systems
自己書き換えコード
シェルコード
スタックバッファオーバーフロー




もう一度検索

【記事の利用について】

タイトルと記事文章は、記事のあるページにリンクを張っていただければ、無料で利用できます。
※画像は、利用できませんのでご注意ください。

【リンクついて】

リンクフリーです。