- 首先構建一個含有緩沖區(qū)溢出的C語言程序崇摄。
源碼如下:
#include <stdio.h>
#include <windows.h>
#define PASSWORD "1234567"
int verify (char * password)
{
int flag;
char buffer[44];
flag = strcmp(password,PASSWORD);
strcpy(buffer,password);
return flag;
}
void main()
{
int vaild_flag=0;
char password[1024];
FILE * fp;
LoadLibrary("user32.dll");
if (!(fp=fopen("password.txt","rw+")))
{
exit(0);
}
fscanf(fp,"%s",password);
vaild_flag = verify(password);
if (vaild_flag)
{
printf("Incorrect!!!!!!\n");
}
else
{
printf("Congratulation!Gay!you have passed!!!!!\n");
}
fclose(fp);
getchar();
}
因為在程序輸入中手動輸入shellcode較為困難拉鹃。所以我們用password.txt作為輸入源辈赋,shellcode也將寫入其中。
從程序可知當我們輸入錯誤的密碼的時候毛俏。
flag在內存的值為00000001炭庙,此時彈出提示信息“Incorrect!!!!!!”饲窿。那么有什么方法在不合法的輸入前提下可以讓flag為00000000呢 煌寇?
根據(jù)棧的結構函數(shù)在棧中的空間分配應該為以下所示:
buffer[0…3]
……
buffer[40…43]
flag
EBP
返回地址
- C語言中有一個字符結束標志'\0'
我們可以通過填滿緩沖區(qū)使位于字符末位的0,跨界溢出到flag的1上使flag=00000000逾雄。
未受溢出的flag
受溢出影響的flag
用44個字符填充buffer
- 既然已經覆蓋了鄰接變量flag阀溶,那么我們是不是也可以覆蓋掉返回地址,使得返回地址指向我們想讓執(zhí)行的地方并在其中放上shellcode鸦泳。
當然只需要在password中再寫入三個dword银锻,第一個覆蓋flag,第二個覆蓋EBP做鹰,第三個覆蓋返回地址击纬。
-
在password.txt中放入shellcode并使返回地址指向buffer的偏移地址0012FAEC(ollydbg中得到)。
最后四位是buffer地址(注意順序)
shellcode成功執(zhí)行
shellcode的編寫
用匯編語言編寫之后(可用高級語言通過編譯器查看)
用所用機器的CPU指令集钾麸,將其寫為16進制代碼更振。Shellcode便制作成功了炕桨。
此處的shellcode是調用系統(tǒng)的動態(tài)鏈接庫中的messageboxA.dll
將地址寫入
用APIAdress.exe可以查看API所在的入口地址。