A. 緩沖區溢出的攻擊
通過往程序的緩沖區寫超出其長度的內容,造成緩沖區的溢出,從而破壞程序的堆棧,造成程序崩潰或使程序轉而執行其它指令,以達到攻擊的目的。造成緩沖區溢出的原因是程序中沒有仔細檢查用戶輸入的參數。
下面通過一個示例來詳細看看什麼是緩沖區溢出。程序的緩沖區就像一個個格子,每個格子中存放不同的東西,有的是命令,有的是數據,當程序需要接收用戶數據,程序預先為之分配了4個格子(下圖1中黃色的0~3號格子)。按照程序設計,就是要求用戶輸入的數據不超過4個。而用戶在輸入數據時,假設輸入了16個數據,而且程序也沒有對用戶輸入數據的多少進行檢查,就往預先分配的格子中存放,這樣不僅4個分配的格子被使用了,其後相鄰的12個格子中的內容都被新數據覆蓋了。這樣原來12個格子中的內容就丟失了。這時就出現了緩沖區(0~3號格子)溢出了。
在上面示例的基礎上來看一個代碼實例,程序如下:
void function(char *str) {
char buffer[16];
strcpy(buffer,str);
}
上面的strcpy()將直接把str中的內容到buffer中。這樣只要str的長度大於16,就會造成buffer的溢出,使程序運行出錯。存在象strcpy這樣的問題的標准函數還有strcat(),sprintf(),vsprintf(),gets(),scanf()等。
當然,隨便往緩沖區中填東西造成它溢出一般只會出現「分段錯誤」(Segmentation fault),而不能達到攻擊的目的。最常見的手段是通過製造緩沖區溢出使程序運行一個用戶shell,再通過shell執行其它命令。如果該程序有root或者suid執行許可權的話,攻擊者就獲得了一個有root許可權的shell,可以對系統進行任意操作了。
緩沖區溢出攻擊之所以成為一種常見安全攻擊手段其原因在於緩沖區溢出漏洞太普遍了,並且易於實現。而且,緩沖區溢出成為遠程攻擊的主要手段其原因在於緩沖區溢出漏洞給予了攻擊者他所想要的一切:植入並且執行攻擊代碼。被植入的攻擊代碼以一定的許可權運行有緩沖區溢出漏洞的程序,從而得到被攻擊主機的控制權。
在1998年Lincoln實驗室用來評估入侵檢測的的5種遠程攻擊中,有2種是緩沖區溢出。而在1998年CERT的13份建議中,有9份是是與緩沖區溢出有關的,在1999年,至少有半數的建議是和緩沖區溢出有關的。在Bugtraq的調查中,有2/3的被調查者認為緩沖區溢出漏洞是一個很嚴重的安全問題。
緩沖區溢出漏洞和攻擊有很多種形式,會在第二節對他們進行描述和分類。相應地防衛手段也隨者攻擊方法的不同而不同,將在第四節描述,它的內容包括針對每種攻擊類型的有效的防衛手段。 緩沖區溢出攻擊的目的在於擾亂具有某些特權運行的程序的功能,這樣可以使得攻擊者取得程序的控制權,如果該程序具有足夠的許可權,那麼整個主機就被控制了。一般而言,攻擊者攻擊root程序,然後執行類似「exec(sh)」的執行代碼來獲得root許可權的shell。為了達到這個目的,攻擊者必須達到如下的兩個目標:
1. 在程序的地址空間里安排適當的代碼。
2. 通過適當的初始化寄存器和內存,讓程序跳轉到入侵者安排的地址空間執行。
可以根據這兩個目標來對緩沖區溢出攻擊進行分類。
B. 緩沖區溢出的基本原理是什麼
緩沖區溢出的原理:
通過往程序的緩沖區寫超出其長度的內容,造成緩沖區的溢出,從而破壞程序的堆棧,使程序轉而執行其它指令,以達到攻擊的目的。造成緩沖區溢出的原因是程序中沒有仔細檢查用戶輸入的參數。例如下面程序:
void function(char *str) {
char buffer[16];
strcpy(buffer,str);
}
上面的strcpy()將直接吧str中的內容到buffer中。這樣只要str的長度大於16,就會造成buffer的溢出,使程序運行出錯。存在象strcpy這樣的問題的標准函數還有strcat(),sprintf(),vsprintf(),gets(),scanf()等。
漏洞:
緩沖區溢出攻擊的目的在於擾亂具有某些特權運行的程序的功能,這樣可以使得攻擊者取得程序的控制權,如果該程序具有足夠的許可權,那麼整個主機就被控制了。一般而言,攻擊者攻擊root程序,然後執行類似「exec(sh)」的執行代碼來獲得root許可權的shell。為了達到這個目的,攻擊者必須達到如下的兩個目標:
在程序的地址空間里安排適當的代碼。
通過適當的初始化寄存器和內存,讓程序跳轉到入侵者安排的地址空間執行。
可以根據這兩個目標來對緩沖區溢出攻擊進行分類。
以上內容參考:網路-緩沖區溢出
C. 用C語言寫一段程序,模擬函數緩沖區溢出攻擊(buffer overrun)。
這個基本上沒辦法給你寫例子,受編譯環境影響太大。
原理很單純,就是把函數局部變數作為基址可以直接修改函數的返回地址。用匯編很好辦,但C的話很多必要地址只能編譯好了才能知道。
----
VS2008 Debug模式編譯 關閉Incremental Linking
#include <stdio.h>
void foo();
// __stdcall為了foo2在返回的時候清理foo1調用時候的參數,因為是通過返回進入foo2的,所以foo1的返回地址已經出棧,現在棧里還剩下foo1的兩個參數,我們需要第一個參數的位置作為foo2的返回值
// 於是還剩一個參數的位置,foo2也有一個參數,利用__stdcall自己清理參數的特性就可以把剩下的那個參數清理掉。然後我們直接返回到foo1調用後清理參數的代碼之後,避免棧混亂。
void __stdcall foo2(void *mmy)
{
printf("foo2...\n當前返回地址: %.8X,位於: %.8X\n", *(&mmy - 1), &mmy - 1);
*(int *)(&mmy - 1) = (int)foo + 0x3A; // 這里的0x3A只有編譯後看生成的匯編才能得到。
printf("替換返回地址為foo1返回並清理堆棧後...\n當前返回地址: %.8X,位於: %.8X\n", *(&mmy - 1), &mmy - 1);
}
void foo1(int in_offset, int in_data)
{
int buf[0x10];
printf("foo1...\n當前返回地址: %.8X,位於: %.8X\n", *((void **)&in_offset - 1), (void **)&in_offset - 1);
buf[in_offset] = in_data; // 這里buf + in_offset指向的是foo1的返回地址,foo1返回的時候會跳轉的foo2的入口
printf("替換...\n當前返回地址: %.8X,位於: %.8X\n", *((void **)&in_offset - 1), (void **)&in_offset - 1);
}
void foo()
{
printf("foo...\n調用foo1, 通過非法索引將foo1返回地址替換為foo2人口...\n");
foo1(18, (int)foo2); // 這里的18是返回地址相對buf的偏移量,只有編譯之後才能獲得。VC環境下Debug模式是16個buf元素+1個保護數據+1個過去的幀指針。
}
void main()
{
foo();
}
D. 溢出攻擊的緩存區溢出
通過往程序的緩沖區寫超出其長度的內容,造成緩沖區的溢出,從而破壞程序的堆棧,使程序轉而執行其它指令,以達到攻擊的目的。造成緩沖區溢出的原因是程序中沒有仔細檢查用戶輸入的參數。例如下面程序:
void function(char *str) {
char buffer[16];
strcpy(buffer,str);
}
上面的strcpy()將直接把str中的內容到buffer中。這樣只要str的長度大於16,就會造成buffer的溢出,使程序運行出錯。存在象strcpy這樣的問題的標准函數還有strcat(),sprintf(),vsprintf(),gets(),scanf()等。
當然,隨便往緩沖區中填東西造成它溢出一般只會出現「分段錯誤」(Segmentation fault),而不能達到攻擊的目的。最常見的手段是通過製造緩沖區溢出使程序運行一個用戶shell,再通過shell執行其它命令。如果該程序屬於root且有suid(Set User ID,)許可權的話,攻擊者就獲得了一個有root許可權的shell,可以對系統進行任意操作了。
緩沖區溢出攻擊之所以成為一種常見安全攻擊手段其原因在於緩沖區溢出漏洞太普遍了,並且易於實現。而且,緩沖區溢出成為遠程攻擊的主要手段其原因在於緩沖區溢出漏洞給予了攻擊者他所想要的一切:植入並且執行攻擊代碼。被植入的攻擊代碼以一定的許可權運行有緩沖區溢出漏洞的程序,從而得到被攻擊主機的控制權。
在1998年Lincoln實驗室用來評估入侵檢測的的5種遠程攻擊中,有2種是緩沖區溢出。而在1998年CERT的13份建議中,有9份是是與緩沖區溢出有關的,在1999年,至少有半數的建議是和緩沖區溢出有關的。在Bugtraq的調查中,有2/3的被調查者認為緩沖區溢出漏洞是一個很嚴重的安全問題。
緩沖區溢出漏洞和攻擊有很多種形式,會在第二節對他們進行描述和分類。相應地防衛手段也隨者攻擊方法的不同而不同,將在第四節描述,它的內容包括針對每種攻擊類型的有效的防衛手段。