小目次

目次にもどる
ーサンプルプログラムの実行結果
ー修正したプログラム
ー修正したプログラムの実行結果
ーバッファオーバーフローによるTCP/IPのセキュリティ欠陥

課題6:バッファオーバーフローの実験

サンプルプログラム(2) (ここに入っているのいはゆ~すけが編集済みのプログラムです、正式版は先生のサイトからダウンロードしてください) を実行せよ。このプログラムはgets()関数を用いて、標準入力からの入力をバッファにデータを読み込むものであるが、結果を見ると、プログラム中で操作していないバッファdmy[]に値が入ることがある。この原因を考察し、解決策を示せ。また、この問題によって引き起こされるTCP/IP通信におけるセキュリティ上の欠陥はどのようなものが考えられるか、具体例を挙げて述べよ。


サンプルプログラムの実行結果

200文字入力するのは面倒なので「#define BUFLEN 5」にして実行
%./bufovf
before
buf(Len:0) =
dmy(Len:0) =
warning: this program uses gets(), which is unsafe.
4627861872349872193472937498326587269487123984628651937821734021874241985
after
buf(Len:73) = 4627861872349872193472937498326587269487123984628651937821734021874241985
dmy(Len:0) =
Segmentation fault
dmyに「Segmentation fault 」が出ていることから、dmyになにかよけいな値が入ってしまっていることがわかる。


修正したプログラム

bufovf.cのソースコード(別ウィンドウ)
使われている関数については関数メモを参照

gets関数は配列の長さを指定することができないので、許容量以上の入力を妨げることができない。
そこで文字数を指定でき、改行コードも入力されるfgets関数を使用した。

使い方は
fgets(char 文字列配列, int 入力したい文字数+1, FILE 入力ストリーム);
改行コードも入力されるので「入力したい文字数+1」にするのを忘れないようにする。
作成したプログラムではBUFLENが5になっているので4文字までしか入力できない。
ちなみに、「stdin」は「標準入力」のこと。


修正したプログラムの実行結果

%./bufovf
before
buf(Len:0) =
dmy(Len:0) =
4627861872349872193472937498326587269487123984628651937821734021874241985
after
buf(Len:4) = 4627
dmy(Len:0) =

BUFLENが5になっているので、最初の4文字が入力されて残りは無視される。

バッファオーバーフローによるTCP/IPのセキュリティ欠陥

バッファオーバーフローが発生するということは、「プログラマが意図していない領域に値が書き込まれる」ということである。
もし仮に、バッファオーバーフローが起こった際に不正なデータが書き込まれる先が他のプログラムのデータ領域だった場合、そのプログラムが改変されることになり、プログラマが意図していない動作、例えばクラッキングなどに利用される恐れがある。
よってバッファオーバーフローは重大なセキュリティホールになり得る。
上にもどる
目次にもどる