バッファオーバーラン

こちらのCのソースをご覧下さい。 FreeBSD/i386だと、このコードは何故かbazという関数を呼びます。
> ./a.out
hello world
foo.c
bar.c
b:0xefbfd7ac
main:0x1694
0x16c8
Oh My God
Segmentation fault (core dumped)
これはどういう事かというと、関数の呼び出しでは、呼び出し元の アドレスをスタックに積んで呼ぶわけです(少なくともi386アーキテクチャの場合)。 スタックの説明の図 で、自動変数だとそれも、スタックに積まれるわけで、普通に使う分には それらは気にしなくていいわけです。今の場合は、戻り値の部分をbazのアドレスで 上書きしたため、mainに戻る代わりにbazが呼び出されたわけです。 今の場合はかなり変てこな例ですけど、 自動変数の配列をスタックにとっている場合これはかなり危なくて、 バッファオーバーランをすると容易にこういう事が起こるわけです。 ただたいていの場合はアドレスとしてはゴミが入る場合が多いので単に SEGVが起こるだけで済むわけですが、悪意ある人の手にかかると そうは行きません。例えばgets()あたりを使って居る場合わざとバッファオーバーラン させて、くだんの戻り先にスタック上の次のアドレス(図の*)を上書きするようにして さらに、その後ろ(図で*の部分)に色々悪事を働くコードを書かれたとしたら .......想像するだに恐ろしいですね。これが、popperやbindで 問題になったやつの正体なわけです。 もちろんこういうものを検出するツールと言う物は存在していて、中には ソースコードが無くても関数のシンボルテーブルがあれば、どこの 関数で起こっているか指摘する事の出来るツールがあるわけで、 ソースを隠しておけばこういう事が防げるかと言うと全然そんな事は無いわけです。 しかし、これってはっきり言ってクラッカー養成講座のような気がしないでもない。 ここがおかしい,嘘だろこれ,こんなモン公開すんなボケ。ってな御意見が ありましたら/dev/null まで。