栈溢出的简单利用
前言
最近学校的一些课程简单提到了一些栈溢出的相关危害,并提供一个实验让我们尝试利用缓冲区溢出来打开notepad.exe
,并可以尝试在多个操作系统上达到通用性。
实验内容
此次实验采用
VS
完成,实验开始前记得关闭VS
的各项安全保护机制
基础实验
此次实验我们的溢出点为以下代码:
1 |
|
我们需要做的是编写一个shellcode
来执行WinExec
以及ExitProcess
我们先观察已给出的程序,我们可以看到buf
的大小为 10,我们对buf
拷贝数据时会默认在后面添加一个0x00,然后进行字节对齐其长度应该为12也就是 0x0C
我们可以绘制出以下图:
可以看到我们的返回地址在我们的下面16字节处,我们构建一个Shellcode
长为16的0x90
,将其进行覆盖,随后我们找到一个jmp esp
指令的地址,我们将返回地址设置为该指令的地址
此时shellcode为:
1 |
|
随后我们通过Kernel32.dll来获取相关调用函数的绝对地址
我们将其进行记录,为后续编写ShellCode做准备
我们前面找到了jmp esp
的代码,接下来其执行的地址空间就是我们ShellCode
的后续内容,我们将字符串C:\notepad.exe
进行压入栈中,需要注意一下小端序是逆序压入。之后我们压入WinExec
的参数以及通过将绝对地址给eax
,通过call eax
对其进行执行
我们构造的ShellCode
变为如下:
1 |
|
我们执行完后因为后续程序地址空间内为0x00
(Release下)或0xCC
(Debug下)
所以会引发执行异常,我们可以采用调用一个ExitProcess(0)
来解决上述问题
此时我们的ShellCode为:
1 |
|
我们进行调试运行可以看到我们成功的将返回地址进行覆盖,然后执行内容为我们ShellCode中的汇编代码指令
最后我们可以和成功的打开在根目录下的notepad.exe
程序
进阶实验
那么我们对于任意版本的Windows
操作系统需要实现通用性便需要通过获取Kernel32.dll
的基址,我们通过遍历其导出表来获取对应我们需要调用的函数地址,通过获取到的地址再进行调用即可完成对应操作
代码如下:
1 |
|
上述代码为简便我们直接自己开启一个后门,通过其来完成对应内容实现,我们可以成功的在各个操作系统下成功进行调用