当前位置: 移动技术网 > 科技>办公>CPU > 简单实现栈溢出实验(IDA)

简单实现栈溢出实验(IDA)

2020年10月10日  | 移动技术网科技  | 我要评论
有关栈溢出的相关知识最近学校讲到了栈溢出,并有一道很基础的题,在此可以记录一下,感兴趣的人可以了解了解

有关栈溢出的相关知识

最近学校讲到了栈溢出,并有一道很基础的题,在此可以记录一下,感兴趣的人可以了解了解.
/
栈溢出:
/
首先谈到栈溢出,要先说windows系统典型漏洞分析。
/
栈溢出也是其中的一种。
/
要了解栈溢出,要先了解:

1.主角:栈 与 栈帧

栈(音:zhan四声)是一种特殊的线性计算机内部存储结构,服从先进后出的一种特殊线性结构,如同弹夹里的子弹,先放入的子弹,在最下面。栈的结构使其只能在栈的顶端进行增加数据和删除数据的操作,压入数据称为(push),弹出数据称为(pop).
/

2.内存结构

在win32环境下,由高级语言生成的可执行文件,即PE文件,(Portable Executable)文件。在运行可执行文件时,系统会将其加载到内存,并映射出4GB的虚拟存储空间,然后继续运行,形成所谓的进程空间。(教材原话)
/
在win32中将进程使用的内存按功能可以分为4个区域,如下图:
/

名称作用
栈区(stack)用于动态存储函数之间的调用关系低地址
堆区该内存区域由进程利用相关函数和运算符动态申请
代码区存放程序汇编之后的机械代码和只读程序,计算机运行程序,会在该区域读取命令并执行。
数据区用于存储全局变量和静态变量高地址

/
其在计算机内存中的结构也如下图:

栈区↑栈增长方向
堆区↓堆增长方向
代码区
数据区

代码实现

/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void attack()
{
	printf("TRY IT!.\n");       //attack函数
}
void func()                     //func函数
{
	char password[6] = "ABCDEF";
	char str[6];
	FILE *fp;
	if(!(fp=fopen("D:\\password.txt","r"))) //打开D盘的password.txt文件
		exit(0);
	fscanf(fp,"%s",str);           //将str的内容写入fp
	str[5]='\0';
	if(strcmp(str,password)==0)    //判断str是否与password相同
		printf("OK.\n");
	else
		printf("NO.\n");            
}
int main()
{
	func();          //运行func函数
	return 0;
}

/

用软件IDA实现栈溢出实验(步骤)

/在这里入图片描述
在D盘的password.txt中输入一定量的字符串,运行程序,AAAAA…与指定的password并不相同,所以返回了“NO”。

现在打开IDA.

1.打开

可以将exe文件拖入其中
得到如下:
/在这里插入图片描述
/
现在展示的IDA适用静态调试,左边可以清晰地看到函数体,这是IDA比较清晰简便的一个优点。

2.寻找函数名称

在这里插入图片描述
点击左侧的函数名可以进入。右侧也可以查看十六进制视图:在这里插入图片描述
IDA快捷键,按F5可以查看伪代码。伪代码可以让人较为清晰地了解函数的部分构造,但不是能运行的代码。在这里,用鼠标左键双击左侧函数名称中的func(),再按F5可以进入func函数查看伪代码:

3. F5查看伪代码

在这里插入图片描述

在这里插入图片描述
在上图中点击各个变量,可以查看栈。

4.查看栈

在这里插入图片描述

查看到str,password,fp在栈中的位置

/

注意到最下面有一个"r"

/

这里"r"指的是return adress,这里简述为ret,ret指的是返回地址,ret在汇编中也有涉及。
这里的ret主要功能是返回下一个函数的地址,用于在一个函数运行完后跳转到下一个函数,栈溢出攻击在这里运行的原理是,通过文本中读入过量的数据,从而,是数据在栈上溢出,使其覆盖正常的数据,从而引起漏洞与异常。

/

如果,溢出的数据覆盖了ret地址,那么函数可以跳转到一个指定的函数,即上文的“attack”函数。

/

所以在这里开始,找到attack函数的地址:

在这里插入图片描述
然后,只要将attack()的地址,输入到文本的末尾即可。但是,要满足其刚好能将ret的地址覆盖,使函数跳转异常,从而跳转到指定的攻击函数。
/

那么,来计算一下,在文本中输入多少个字符会刚刚覆盖到“r”,处:

/

这里查看到这个信息: [esp+10h] [ebp-18h] (如下图)
/

5.分析怎么实现栈溢出

在这里插入图片描述

由于内存栈区的地址由高地址向低地址增长,当4个字节压入栈帧时,即为 ESP=ESP-4, 有4个字节弹出栈帧时, ESP=ESP+4.

ESP(extended stack point)是扩展栈指针寄存器,其存放地址指向这个栈帧的栈顶
/
EBP(extended base point)是扩展基址指针寄存器,其存放地址指向这个栈帧的栈底。

/
ESP与EBP之间是当前栈帧的空间。

上图意为,从前栈底到str存放的位置还有18个字节。即[ebp-18h]的含义。

其实从IDA中也能清晰看出来:

在这里插入图片描述
上图中,可以看到变量str,password,fp存放在栈中的位置,可以看到上图用红色框框选的,有18个字节,也就是上文的[ebp-18h],下面蓝色框有10个字节,即到r为止。
/
数据从上方加入,那我们只要在文本前加入(10+18)=28个字节,就可以刚刚覆盖到r处,r是运行完后要跳转的函数地址,那我们在28个直接之后加入,攻击函数attack()的地址即可。
/

在这里插入图片描述
将D盘的password.txt文件拖入软件“HxD”中,一种文本编辑软件,notepad++也可。
输入28个字母,之后将attack()的地址加入,即"00 40 13 50",但这里是小端序。

这里讲一讲:

6.小端序和大端序

字节序即为多字节对象存储在内存中的字节顺序,有两种不同的存储方案:大端法和小端法。现代的处理器大多为双端法,大小端都支持,可以配置称大端法或者小端法。
/
大端序:(Big-endian):高位字节存入低地址,低位字节存入高地址
小端序:(Little-endian):低位字节存入低地址,高位字节存入高地址

7.继续,运行结果,原理

一般x86位的CPU都为小端序:所以在编辑时将地址反着写,写作"50 13 40 00",
然后,点击“保存”文件。
/
再打开编译器,运行:
/
在这里插入图片描述
运行结果出现了TRY IT!,明显这是attack()函数的内容,已经完成了栈溢出,使函数运行出了指定的内容,这就是用IDA实现的简单的栈溢出攻击实验。
/
通过栈上数据的溢出,覆盖了,正确的r返回地址,从而使函数跳转出现失误,或指向性的跳转。可以加以利用。

本文地址:https://blog.csdn.net/fightte/article/details/108834167

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网