注:本文属于个人原创,错误处请各位指正
一、缓冲区溢出
百度百科“缓冲区溢出是一种非常普遍、非常危险的漏洞,在各种操作系统、应用软件中广泛存在。利用缓冲区溢出攻击,可以导致程序运行失败、系统宕机、重新启动等后果。更为严重的是,可以利用它执行非授权指令,甚至可以取得系统特权,进而进行各种非法操作。”
在缓冲区填充超过变量所属内存的长度的字符,超出目标变量内存,可能导致程序出错或不可预知的结果。在精心设计的缓冲区溢出中可发生期待的结果,而正常编程往往难以达到该目的。
二、缓冲区溢出实验
2.1、改变栈内的变量
技术有限,无力过VS提供的保护,是在关闭VS保护下进行试验的。
1、关闭VS保护
项目--》属性--》C/C++--》代码生成 --》基于运行时检查 设置为 :默认值
项目--》属性--》C/C++--》代码生成 --》安全检查 设置为: 禁用安全检查 (/GS-)
项目--》属性--》链接器--》高级--》随机基址 设置为: 否 (/DYNAMICBASE:NO)
项目--》属性--》C/C++--》常规--》SDL检查 设置为:否 (/sdl-)
2、试验源码
#include<iostream>
#include<windows.h>
#include <string.h>
using namespace std;
int overflow(const char* input)
{
BOOL bFlAG = TRUE;
int nFlag = 1;
char buf[8];
memset(buf, 0, 8);
printf("Virtual address of 'buf' = Ox%p\n", buf);
printf("Virtual address of 'nFlag' = Ox%p NUM:%d \r\n", &nFlag, nFlag);
strcpy(buf, input);
printf("Virtual address of 'nFlag' = Ox%p NUM:%d \r\n", &nFlag, nFlag);
return 0;
}
int main()
{
printf("Virtual address of 'overflow' = Ox%p\n", overflow);
//注意这里ff后,但其实默认添加了’\0’在最后面
char input[] = "AAAAAAAB\xff\xff\xff\xff";
overflow(input);
system("pause");
return 0;
}
3、编译运行
在overflow函数处下断点 调出反汇编(Ctrl+Alt+D)
overflow(input);
0041164D lea eax,[input]
00411650 push eax //将参数压入栈中
00411651 call overflow (0411226h) //调用overflow函数
00411656 add esp,4 //栈顶下移四个字节,平衡栈
进入函数overflow,在“BOOL bFlAG = TRUE;”执行前可看到栈顶指针ESP为0x0019FE40,栈底指针为EBP(话外:EIP储存下CPU下一条将要执行指令的地址)
查看内存(Ctrl+Alt+M),输入ESP查看栈 ,栈是向下生长的 栈顶为ESP(1)栈底为EBP(2),EBP后四个字节存储着返回地址00411656
当程序运行到“printf("Virtual address of 'buf' = Ox%p\n", buf);”时我们再看函数栈
黑框框起来的一次是buf,nFlag,bFlag,此时可以看出nFlag为1,bFlag为TRUE;
在“strcpy(buf, input);”函数执行后会发生缓冲区溢出,执行后再查看内存结果为,其中input实际为"AAAAAAAB\xff\xff\xff\xff\x00"
复制后nFlag的内存变为ff ff ff ff (-1),bFlag内存变为 00 00 00 00(FALSE),红色箭头标出的是input的最后一个字符'00'
我们通过缓冲区溢出将nFlag的值由1改为-1。