gets関数の脆弱性


gets関数とfgets関数の最大の違いは、gets関数のバッファがユーザによって提供されるが、ユーザは一度に最大何バイトの内容を読み込むかを指定できないことである.この点getsは非常に危険な関数になりました.
次の例ではgets関数の危険性を示します.このプログラムはバッファを定義しますが、gets関数を使用してユーザーが入力した文字列を受信すると問題が発生します.
(1)viエディタでこのプログラムを編集するには、次のようにします.
プログラムリスト21-5 risk.c gets関数の脆弱性を利用してバッファ攻撃を行う
#include <stdio.h>
int main(void)
{
/*           ,                ,           */
char buf[2048]; 
 while(gets(buf) != buf){ /*            */
printf("%s
", buf); /* */ } return 0; }

(2)shellでこのプログラムをコンパイルするのは以下の通りである.
$gcc risk.c -o risk

(3)shellで実行するプログラムは以下の通りである.
$./risk
hello world (  )
hello world (  )
welcome to the real world, it sucks, but you will love it(  )
welcome to the real world, it sucks, but you will love it(  )

これまで問題は発生していませんが、実際にコマンドライン端末の場合は問題は発生しません.shell端末の入力バッファは1024バイトしかないので、つまり私たちの攻撃は実際にshellに遮られています.
(4)このときは別の方法で,まずこのプログラムを終了する.
$^c 

(5)非常に大きなファイルを指向から標準入力に変換する.
$./risk < big_file.txt 
Segmentation fault

セグメントエラーが発生し、プログラムがクラッシュしました.入力された文字が多すぎてgets関数のバッファが境界を越えたためです.
注意:gets関数は確かに非常に安全ではない関数であることから、筆者は読者にこの関数の使用を推奨しない.