當(dāng)前位置:首頁(yè) > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > 緩沖區(qū)溢出指的是什么
緩沖區(qū)溢出,是針對(duì)程序設(shè)計(jì)缺陷,向程序輸入緩沖區(qū)寫(xiě)入使之溢出的內(nèi)容(通常是超過(guò)緩沖區(qū)能保存的最大數(shù)據(jù)量的數(shù)據(jù)),從而破壞程序運(yùn)行、趁著中斷之際并獲取程序乃至系統(tǒng)的控制權(quán)。
計(jì)算機(jī)程序一般都會(huì)使用到一些內(nèi)存,這些內(nèi)存或是程序內(nèi)部使用,或是存放用戶(hù)的輸入數(shù)據(jù),這樣的內(nèi)存一般稱(chēng)作緩沖區(qū)。溢出是指盛放的東西超出容器容量而溢出來(lái)了,在計(jì)算機(jī)程序中,就是數(shù)據(jù)使用到了被分配內(nèi)存空間之外的內(nèi)存空間。而緩沖區(qū)溢出,簡(jiǎn)單的說(shuō)就是計(jì)算機(jī)對(duì)接收的輸入數(shù)據(jù)沒(méi)有進(jìn)行有效的檢測(cè)(理想的情況是程序檢查數(shù)據(jù)長(zhǎng)度并不允許輸入超過(guò)緩沖區(qū)長(zhǎng)度的字符),向緩沖區(qū)內(nèi)填充數(shù)據(jù)時(shí)超過(guò)了緩沖區(qū)本身的容量,而導(dǎo)致數(shù)據(jù)溢出到被分配空間之外的內(nèi)存空間,使得溢出的數(shù)據(jù)覆蓋了其他內(nèi)存空間的數(shù)據(jù)。
在計(jì)算機(jī)安全領(lǐng)域,緩沖區(qū)溢出就好比給自己的程序開(kāi)了個(gè)后門(mén),這種安全隱患是致命的。緩沖區(qū)溢出在各種操作系統(tǒng)、應(yīng)用軟件中廣泛存在。而利用緩沖區(qū)溢出漏洞實(shí)施的攻擊就是緩沖區(qū)溢出攻擊。緩沖區(qū)溢出攻擊,可以導(dǎo)致程序運(yùn)行失敗、系統(tǒng)關(guān)機(jī)、重新啟動(dòng),或者執(zhí)行攻擊者的指令,比如非法提升權(quán)限。通過(guò)往程序的緩沖區(qū)寫(xiě)超出其長(zhǎng)度的內(nèi)容,造成緩沖區(qū)的溢出,從而破壞程序的堆棧,造成程序崩潰或使程序轉(zhuǎn)而執(zhí)行其它指令,以達(dá)到攻擊的目的。造成緩沖區(qū)溢出的原因是程序中沒(méi)有仔細(xì)檢查用戶(hù)輸入的參數(shù)。
下面通過(guò)一個(gè)示例來(lái)詳細(xì)看看什么是緩沖區(qū)溢出。程序的緩沖區(qū)就像一個(gè)個(gè)格子,每個(gè)格子中存放不同的東西,有的是命令,有的是數(shù)據(jù),當(dāng)程序需要接收用戶(hù)數(shù)據(jù),程序預(yù)先為之分配了4個(gè)格子(下圖中黃色的1~4號(hào)格子)。按照程序設(shè)計(jì),就是要求用戶(hù)輸入的數(shù)據(jù)不超過(guò)4個(gè)。而用戶(hù)在輸入數(shù)據(jù)時(shí),假設(shè)輸入了17數(shù)據(jù),而且程序也沒(méi)有對(duì)用戶(hù)輸入數(shù)據(jù)的多少進(jìn)行檢查,就往預(yù)先分配的格子中存放,這樣不僅4個(gè)分配的格子被使用了,其后相鄰的13個(gè)格子中的內(nèi)容都被新數(shù)據(jù)覆蓋了。這樣原來(lái)13個(gè)格子中的內(nèi)容就丟失了。這時(shí)就出現(xiàn)了緩沖區(qū)(1~4號(hào)格子)溢出了。
如下代碼的問(wèn)題就出在strcpy(buf, s)這條語(yǔ)句上,它將s拷貝到buf中,而沒(méi)有對(duì)s的長(zhǎng)度進(jìn)行限制,這就給緩沖區(qū)溢出攻擊提供了可乘之計(jì)。
#include
#include
void vulFunc(char* s)
{
char buf[10];
strcpy(buf, s);
printf("String=%s\n", buf);
}
main(int argc, char* argv[])
{
if(argc == 2)
{
vulFunc(argv[1]);
}
else
{
printf("Usage: %s \n", argv[0]);
}
}
緩沖區(qū)溢出一般是由于一下原因?qū)е拢?/p>
1.字符串處理函數(shù)沒(méi)有指定長(zhǎng)度,單單憑借結(jié)尾字符是不是'\0'來(lái)判斷結(jié)束。
2.被處理的字符超過(guò)緩沖區(qū)可接受的大小。例如,從屏幕輸入字符串:gets(buff),但是buff的內(nèi)存少于屏幕一行字符個(gè)數(shù),就會(huì)導(dǎo)致溢出,應(yīng)該使用fgets。
3.所有格式化字符串的函數(shù):fprintf("%n",&num_write)。
避免的辦法:
1.不要把用戶(hù)的輸入作為參數(shù)傳到格式化字符串處理函數(shù)中,例如,printf("%s", argv[1])。
2.字符串處理避免使用strcpy,strcat,sprintf,gets。應(yīng)該使用strncpy,strncat,snprintf。strlcpy和strlcat都是NULL結(jié)尾。盡量使用std::string,MFC::CString
3.使用C++ I/O函數(shù)
4.使用安全的C Runtime Time函數(shù)
5.檢查文件路徑的長(zhǎng)度,不要超過(guò)系統(tǒng)允許的最大值。