バッファオーバーフロー(BOF)攻撃

古典的だが侮れない攻撃手法。
システム上でこれに起因する脆弱性が存在すると、任意のコードが実行出来てしまう。
最近だと年末にWMFの処理に関する脆弱性が見つかっている。
http://internet.watch.impress.co.jp/cda/news/2005/12/28/10385.html
 
この攻撃はターゲットへ"システムが想定していないサイズのデータ"を送り込むことでシステムの暴走を誘発する。
C,C++の言語仕様とソフトウェアのバグを利用した攻撃手法であるため、昔から存在し、これからも当分存在する攻撃手法だと思われる。
内部的な構造説明は以下(執筆中)

まず、用語の定義。今後断りがなければ他トピックでも同じ意味で使用します。
PC:パーソナルコンピュータ、ワークステーションなどの総称。
情報:PCが解釈する2進数の羅列。プログラム、データ、アドレス、その他諸々
プログラム:PCの挙動を指定する情報。(サーバーソフトウェアなど)
データ:プログラムが利用する情報。(変数、ファイルなど)
アドレス:目的の情報が存在するメモリ上の位置
 

利用される原理

BOF攻撃は、以下のようなプログラム実行に用いられる原理を悪用して行われる

スタックの仕組み

PCが利用する情報の一部(実行されるプログラム、利用されるデータ、それらが格納された場所etc...)はスタックと呼ばれるメモリ領域に格納される。
ここにはデータが順番に積み重ねられ、最後に入ったデータが最初に出て行く。(LIFO:Last In First Out)逆に言えば、最初に入ったデータが最後に出る。
BOFはこのスタックを悪用することで攻撃を実現する。

スタックに格納される情報

スタックはあるプログラムが別のプログラムを呼び出した時に利用され、大きく分けると以下の2つの情報が格納される。
・戻り先(呼び出し元)のアドレス
・サブルーチン(呼び出されたプログラム)が利用するデータ
ここで戻り先は一つだけ、最初に格納される情報(=最後に解釈されるべき情報)である。
一方でデータは複数、必要なだけ(若しくは入力されただけ)格納される。

攻撃対象となる条件

スタックに格納される情報は前項の通りである。
このうちポイントになるのは後者、サブルーチンが利用するデータ、すなわち"入力されてくるデータ"である。前者はスタックの最下層に、一定サイズのみ格納されるのに対し、後者は必要なサイズ分、若しくは入力されたサイズ分スタックに格納される。(必要な分か、入力された分か、これはプログラムの構造に依る)
ここで重大なポイント、攻撃対象となるのは「必要なだけ」ではなく「入力されただけ」格納するプログラムである。
必要なだけしかデータを格納しないプログラムはBOF攻撃の対象外である。
(必要なだけしか取らない処理=BOF対策が取られたプログラムとも言える)
馬鹿正直に、入力された分全てを格納してしまう(=BOF対策がされていない)プログラムがBOF攻撃を受けるのである。
さて、ではなぜ「入力された分全て」を格納してしまうのがいけないのか。
それが次項にある「オーバーフロー」の脆弱性である。

スタックのオーバーフロー

さて、では前項で攻撃対象となると述べた「入力された全て」を格納するプログラムへ、”スタックのサイズより大きいデータ”が入力されたらどうなるだろうか。
当然プログラムはこれを格納しようする。が、サイズ上それは不可能である。そうするとある種のプログラムは、戻り先を入力されたデータで上書きしてしまう。
そうなれば、正しい戻り先は失われ、入力されたデータがそこに格納される。
そして処理終了後、プログラムは正しい戻り先ではなく、"新たに格納されたデータ"を解釈しようとする。
その解釈結果が、様々な攻撃を実現するわけである。
 
続いて、具体的な攻撃の流れを示す。
 

通常実行のイメージ

1.外部プログラム(サブルーチン)が呼ばれる
2.スタックの底に戻り先アドレスが格納される
3.スタックにサブルーチンが使用する変数や、入力されたデータが格納される
4.必要な処理が全て終わったら、戻り先アドレスを解釈し、呼び出しもとプログラムに戻る
 

BOF攻撃のイメージ

1.外部プログラム(サブルーチン)が呼ばれる
2.スタックの底に戻り先アドレスが格納される
3.スタックにサブルーチンが使用する変数などが格納される
4.攻撃者により、スタックサイズを超えるデータが入力される
5.戻り先アドレスやサブルーチンが利用するべきデータが上書きされる
6.上書きされたデータによりプログラムが異常終了したり、攻撃が行われたりする。
 

想定される被害

上書きされるデータの形により、以下のような被害が想定される

プログラムの異常終了

ある意味最も「まし」な被害。上書きされたデータをプログラムが正しく解釈できない場合、例外処理などが発生してプログラムが異常終了する。オンラインでのBOF攻撃ならばDoS攻撃と見なすことも出来る。

任意のコマンドの実行

戻り先アドレスに該当する部分に攻撃対象PC上の特定のアドレスを指定すれば、プログラムはそれを解釈して攻撃者が指定したアドレスのコマンドを実行する。
たとえばシェルのメモリアドレスを指定すればシェルに戻るため、攻撃者は自由に対象PCを操作できてしまう。

任意のコードの実行

戻り先アドレスに該当する部分にスタック上のアドレスを指定し、さらにそのアドレスに攻撃コードを埋め込めば、その攻撃コードが実行される。これによりトロイやバックドアrootkitを仕込むことも可能。
 

対策

結局はバグを突く攻撃手法であるため、バグを減らすことに終始する。
具体的には
・入力データのサイズをチェックする処理をプログラムに実装する
・プログラムの脆弱性情報を随時収集し、修正パッチをこまめに当てる
などが対策となる。