为什么我的栈没有溢出???
最近在学二进制,垃圾水文,笑一下就好
先来看书上的代码
#include
#include
#include
#define TEMP_BUFF_LEN 8
int bof(const char* buf) {
char temp[TEMP_BUFF_LEN];
strcpy(temp, buf);
return 0;
}
int main() {
char buff[] = "1234567";
MessageBox(NULL, "SampleBOF Test", "SampleBOF", MB_OK);
bof(buff);
printf("SampleBOF End\n");
return 0;
}
稍微看下逻辑
MessageBox是弹出一个对话框,SampleBOF Test
是内容,SampleBOF
是标题;在bof函数内部,将buf赋值给temp,由于长度足够,这个程序正常运行
如果用VS2019编译,要注意改两个配置,一个是字符集编码,还有一个strcpy
的安全选项,如下
_CRT_SECURE_NO_WARNINGS
注:不同机子编译出的地址可能不一样,而且不同编译器编译出来的信息也不一样,不需要和试例完全相同
在OD中打开编译后的二进制文件
因为带上了调试信息所以我们可以看到函数符号,就和用gcc编译加上-g
参数一样
$ gcc -g test.c -o test
简单看一下,找下各个函数地址,玩玩动调
通过搜索字符串的功能可以迅速找到main函数
直接点击用到的字符串就可以跳转到引用的位置,就可以找到相应函数了
重新编译文件
#include
#include
#include
#define TEMP_BUFF_LEN 8
int bof(const char* buf) {
char temp[TEMP_BUFF_LEN];
strcpy(temp, buf);
return 0;
}
int sbofa() {
MessageBox(NULL,
"Congratulations!You have the basic principles of buffers overflow.",
"SampleBOF",
MB_OK);
return 0;
}
int main() {
MessageBox(NULL, "SampleBOF Test", "SampleBOF", MB_OK);
char buff[] = "1234567";
bof(buff);
printf("SampleBOF End\n");
return 0;
}
书本上栈溢出的意思应该是,没有用到sbofa
函数,想通过strcpy
溢出到该函数的返回地址,并将返回地址填充为sbofa
的地址,最终效果是会有两个弹窗
再次在OD中打开,查找sbofa
的地址,是0x00D710A0
然后更改上方的代码为
#include
#include
#include
#define TEMP_BUFF_LEN 8
int bof(const char* buf) {
char temp[TEMP_BUFF_LEN];
strcpy(temp, buf);
return 0;
}
int sbofa() {
MessageBox(NULL,
"Congratulations!You have the basic principles of buffers overflow.",
"SampleBOF",
MB_OK);
return 0;
}
int main() {
MessageBox(NULL, "SampleBOF Test", "SampleBOF", MB_OK);
char buff[] = "123456781234\xD7\x10\xA0"; // 小端序
bof(buff);
printf("SampleBOF End\n");
return 0;
}
但直接这样运行显然是有问题的,就算ASLR关闭,因为代码被改过并重新编译,所以sbofa
的地址是变过的,不再是0xD710A0
此外默认设置下,发生栈溢出时,系统是会检测到的,当时就给你中断,掐掉了,并不能直接看到效果
所以一种思路是关闭这些保护,在看雪上看到这篇文章
https://bbs.pediy.com/thread-259665.htm
按照他的关闭这些保护(主要是检测栈溢出和ASLR),然后重做上述步骤,就可以出来结果
主要是如何让程序正常退出吧,显然我们改了bof
的retn地址,程序被我们引到了非预期的地方,在sbofa
这个函数的retn,没有记录main函数里返回地址,程序是不会正常结束的
但是根据栈溢出原理,我们只要再进行一次溢出,有一种思路是溢出到退出函数的地址,那么程序就能“正常”退出了
我们在OD里继续调试,找到使得整个程序退出的函数
并如下修改sbofa
函数就可以了
int sbofa() {
char temp[TEMP_BUFF_LEN];
char buffer[] = "123456781234\x8B\x11\x41";
MessageBox(NULL,
"Congratulations!You have the basic principles of buffers overflow.",
"SampleBOF",
MB_OK);
strcpy(temp, buffer);
return 0;
}
简单的栈溢出,在windows下的小实验
emmmmm所以计算更改了源码,再次编译后,函数的地址是不变的?