《网络安全技术原理与实践》第六章缓冲区溢出攻击攻击-课本实验

为什么我的栈没有溢出???

最近在学二进制,垃圾水文,笑一下就好

《网络安全技术原理与实践》第六章缓冲区溢出攻击攻击-课本实验

案例代码

先来看书上的代码

#include<stdio.h>
#include<string.h>
#include<windows.h>
#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 Endn");
	return 0;
}

稍微看下逻辑

MessageBox是弹出一个对话框,SampleBOF Test是内容,SampleBOF是标题;在bof函数内部,将buf赋值给temp,由于长度足够,这个程序正常运行

image-20211101024404736

如果用VS2019编译,要注意改两个配置,一个是字符集编码,还有一个strcpy的安全选项,如下

image-20211101025202858

_CRT_SECURE_NO_WARNINGS

image-20211101025253758

OD调试

注:不同机子编译出的地址可能不一样,而且不同编译器编译出来的信息也不一样,不需要和试例完全相同

在OD中打开编译后的二进制文件

因为带上了调试信息所以我们可以看到函数符号,就和用gcc编译加上-g参数一样

$ gcc -g test.c -o test

image-20211101034540588

简单看一下,找下各个函数地址,玩玩动调

通过搜索字符串的功能可以迅速找到main函数

image-20211108111949465

直接点击用到的字符串就可以跳转到引用的位置,就可以找到相应函数了

image-20211108112109797

缓冲区溢出利用

重新编译文件

    #include<stdio.h>
    #include<string.h>
    #include<windows.h>
    #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 Endn");
        return 0;
    }

书本上栈溢出的意思应该是,没有用到sbofa函数,想通过strcpy溢出到该函数的返回地址,并将返回地址填充为sbofa的地址,最终效果是会有两个弹窗

再次在OD中打开,查找sbofa的地址,是0x00D710A0

image-20211101044746035

然后更改上方的代码为

#include<stdio.h>
#include<string.h>
#include<windows.h>
#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[] = "123456781234xD7x10xA0";	// 小端序
	bof(buff);
	printf("SampleBOF Endn");
	return 0;
}

但直接这样运行显然是有问题的,就算ASLR关闭,因为代码被改过并重新编译,所以sbofa的地址是变过的,不再是0xD710A0

此外默认设置下,发生栈溢出时,系统是会检测到的,当时就给你中断,掐掉了,并不能直接看到效果

所以一种思路是关闭这些保护,在看雪上看到这篇文章

https://bbs.pediy.com/thread-259665.htm

按照他的关闭这些保护(主要是检测栈溢出和ASLR),然后重做上述步骤,就可以出来结果

image-20211104153528098

课后习题

主要是如何让程序正常退出吧,显然我们改了bof的retn地址,程序被我们引到了非预期的地方,在sbofa这个函数的retn,没有记录main函数里返回地址,程序是不会正常结束的

但是根据栈溢出原理,我们只要再进行一次溢出,有一种思路是溢出到退出函数的地址,那么程序就能“正常”退出了

我们在OD里继续调试,找到使得整个程序退出的函数

image-20211104164024224

并如下修改sbofa函数就可以了

int sbofa() {
	char temp[TEMP_BUFF_LEN];
	char buffer[] = "123456781234x8Bx11x41";
	MessageBox(NULL,
		"Congratulations!You have the basic principles of buffers overflow.",
		"SampleBOF",
		MB_OK);
	strcpy(temp, buffer);
	return 0;
}

分析总结

简单的栈溢出,在windows下的小实验

emmmmm所以计算更改了源码,再次编译后,函数的地址是不变的?

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>