本篇是逆向分析的延伸篇,講的是關於緩衝區溢出。簡單來講,緩衝區溢出就是“輸入數據超出了程序規定的內存範圍,數據溢出導致程序發生異常”,黑客通過緩衝區溢出後,重寫棧中的ret_addr內容來執行任意代碼。
在對緩衝區攻擊前,我們需要了解棧是如何使用內存空間的。棧是一種內存的使用方式,採用LIFO即後進先出,像手槍的子彈一樣。
如下代碼:
void func(int x,int y,int z){
int a;
char buff[6];
}
int main(){
func (1,2,3);
return 0;
}
當調用func函數時,在跳轉至函數起始地址的瞬間,棧的形式如下圖:
基地址爲內存高位,從後向前(向地址遞減方向)增長, $1、$2、$3爲方法變量地址,ret_addr爲main函數返回目標地址。
接下來 esp/rsp逐漸遞減,爲函數內部的局部變量分配內存空間,如下圖:
這時,如果數據溢出,超過了原本分配給buff數組的內存空間,數組後面的ebp、ret_addr以及傳遞給函數的參數都會被溢出的數據覆蓋掉,如下圖:
一旦 ebp和ret_addr被覆蓋掉,將會引發嚴重的後果,ret_addr存放的爲main函數返回目標地址,也就是說,如果覆蓋ret_addr,攻擊者就可以讓程序跳轉至任意地址,如果攻擊者事前準備一段shellcode,然後讓程序跳轉至這段代碼,也就相當於成功攻擊了”可執行任意代碼的漏洞“。
關於shellcode方面,簡單的shellcode代碼如下:
#include <unistd.h>
int main()
{
char *shell[2];
shell[0]="/bin/sh";
shell[1]=NULL;
execve(shell[0],shell,NULL);
}
該代碼功能就是啓動/bin/sh。通過該代碼,我們可以將其轉換爲彙編語言,首先我們對程序進行調試,查看反彙編:
通過反彙編信息,形成彙編語句,如下:
global _start
_start:
xor eax,eax
push eax
push 0x68732f2f
push 0x6e69622f
mov ebx,esp
push eax
push ebx
mov ecx,esp
xor eax,eax
mov al, 0x3b
int 0x80
執行以下語句:
nasm -f elf testshell.asm
ld -m elf_i386 -o testshell testshell.o
最終形成16進制code碼,如下圖:
將上圖16進制代碼整合後,形成執行文件即可。