->back to toppage

課題内容

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

プログラム

サンプルプログラムをそのまま使用した場合、dmy[]に値が入る事がないのでdmy[]とbuf[]の宣言の順番を入れ換えた。また、サンプルプログラムのままでは配列が大いため、バッファオーバーフロー起こすためには標準入力から大量にデータを入力しないといけなく効率が悪かったので、配列のサイズを小さくした。

< tt>#include <stdio.h>

#define BUFLEN 20

int main(int argc, char **argv) {

  char *rtn;
  char buf[BUFLEN];
  char dmy[BUFLEN];

  memset(dmy, '\0', BUFLEN);
  memset(buf, '\0', BUFLEN);

  printf("before\n");

  printf("buf(Len:%d) = %S\n", strlen(buf), buf);
  printf("dmy(Len:%d) = %s\n", strlen(dmy), dmy);

  if ((rtn = gets(buf)) == NULL) {
    exit(-1);
  }

  printf("after\n");
  printf("buf(Len:%d) = %s\n", strlen(buf), buf);
  printf("dmy(Len:%d) = %s\n", strlen(dmy), dmy);

}

実験結果

標準入力から52文字入力した場合、後ろの20文字がdmy[]に入った。

nw0436:~/Desktop/bufovf j04036$ ./a.out 
before
buf(Len:0) = 
dmy(Len:0) = 
warning: this program uses gets(), which is unsafe.
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
after
buf(Len:52) = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
dmy(Len:20) = GHIJKLMNOPQRSTUVWXYZ
nw0436:~/Desktop/bufovf j04036$ 

操作をしていないdmy[]までにもデータが入ってしまった理由は、buf[]に割り振られたメモリ領域を超えてdmy[]のメモリ領域までデータがはみ出たためである。今回の実験の場合、メモリ上ではbuf[]とdmy[]用に20バイトずつ領域が確保され、buf[]とdmy[]の間には12バイトのメモリ領域があることが分かる。

解決法

このバッファオーバーフローの回避する方法としては、buf[]のサイズ以上データの入力を受け付けなくすればよい。それを実装する方法としては、gets()の代わりにfgets()を使用する方法がある。具体的にはgets(buf)のところをfgets(buf, sizeof(buf), stdin)とすればよい。試しに、変更して実行してみる。

nw0436:~/Desktop/bufovf j04036$ ./a.out 
before
buf(Len:0) = 
dmy(Len:0) = 
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
after
buf(Len:19) = abcdefghijklmnopqrs
dmy(Len:0) = 
nw0436:~/Desktop/bufovf j04036$ 

入力は52文字だが、buf[]には19文字までしか入らず、dmy[]には何も入っていないことが確認できる。なお、20バイトのbuf[]に19文字しか入っていないが、これは20バイト目に文字列終端文字のnullが入るためである。

TCP/IP通信におけるセキュリティ上の欠陥

バッファオーバーフローを悪用し、悪意のあるプログラムを入力しさらに関数の戻り値をそのアドレスを悪意のあるプログラムのアドレスに上書きすることによって本来の動作とは異なった動作をすることができる。これによってこのプログラムの持つアクセス権の範囲内で任意の動作を行うことができる。これによってプログラムをクラッシュさせたり場合によってはroot権限を乗っ取られることもある。コンピュータウィルスの中にも同様にバッファオーバーフローを利用し感染を広げていく物がある。このバッファオーバーフロー利用した攻撃は、特定のポートに送るパケットの中に悪意のあるプログラムを忍び込ませてあることが多い。


->previous problem
->go to toppage