简单实现栈溢出实验(IDA)
有关栈溢出的相关知识
最近学校讲到了栈溢出,并有一道很基础的题,在此可以记录一下,感兴趣的人可以了解了解.
/
栈溢出:
/
首先谈到栈溢出,要先说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.打开
得到如下:
/
/
现在展示的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
上一篇: 影视中断案如神的狄仁杰,历史上到底是什么样的人呢?
下一篇: 蜀汉为什么会内斗不断?是什么原因导致的