gets函式的漏洞

shupan001發表於2011-10-11


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\n", 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函式確實是一個非常不安全的函式,所以筆者不推薦讀者使用該函式。


相關文章