实验二:缓冲区溢出实验(war-ftp 1.65)
一、实验目的
1、掌握缓冲区溢出的原理
缓冲区是程序运行期间在内存中分配的一个连续的区域,用于保存包括字符数组在内的各种数据类型。溢出就是所填充的数据超过原有的缓冲区边界,使程序按照其他的流程运行。缓冲区溢出就是向固定长度的缓冲区中写入超出其预告分配长度的内容,造成缓冲区中数据的溢出,从而覆盖了缓冲区周围的内存空间。缓冲区溢出攻击的目的一般在于取得程序的控制权。
2、掌握常用的缓冲区溢出方法
攻击者一般在程序的特定的位置植入攻击代码,然后通过适当的构造寄存区和内存让程序跳转到特定的攻击者安排的特定位置,从而达到控制程序的目的。
3、理解缓冲区溢出的危害
与其他的攻击方式相比,缓冲区溢出攻击更具有破坏性和隐蔽性,破坏性在于它极容易使程序停止运行、服务器死机甚至删除服务器上的数据,隐蔽性在于编写的程序员很可能没有意识到,且植入的代码执行时间短,而且不会影响程序的运行,不一定会被发现。
4、掌握防范和避免缓冲区溢出攻击的方法
首先要避免使用的编程语言中的bug,做好使用函数的边界检查;使用更安全的编译器进行编译,严格进行边界检查;使用更安全的高级语言来避免出现这种错误;设置缓冲区地址空间的属性为不可执行,使得攻击代码不可执行从而避免攻击,即非执行缓冲区技术;保护系统信息,关闭不需要的服务,使用最小权限原则,及时打补丁来避免。
二、实验环境
本实验是在Windows XP SP2环境中,于VM ware虚拟机上进行的,对于war-ftp 1.65的漏洞进行分析和实践,从而深入了解和分析war-ftp 1.65漏洞。
三、实验工具与背景
1、实验工具
本实验重点分析的是war-ftp 1.65的缓冲区溢出漏洞,使用到的调试工具是CDB和OllyDBG。
① War-ftp1.65:一个带有缓冲区漏洞的免费开源的FTP服务器软件,支持大多数的Windows系统。
② CDB:Debugging Tools for Windows,调试工具
③ 堆栈指针定位工具:ActivePerl,提供perl的运行环境;安装metasploit后frameworklib的PatternCreate.pl用于构造一个不重复的超长字符串;framework/sdk下的patternOffset.pl用于计算前面字符串中某段字符的地址偏移量。
实验背景
在课件中已经指出,war-ftp漏洞是:向服务器发送超过480字节的用户名可以出发漏洞(即使用命令USER longStringrn),溢出之后,ESP中的内容包含了longString中的部分内容。本实验通过对该漏洞的分析分析堆栈中EIP、ESP、EBP的位置,从网络上找到已有的shellcode,利用该软件的缓冲区溢出漏洞完成打开计算机的计算器的功能。
四、实验过程
1、验证War-ftp v1.65基于用户名的缓冲溢出漏洞
与助教老师演示的另外一个实验一样,我们首先直接对war-ftp输入不同长度的字符’A’,观察不同长度的字符’A’输入会不会触发缓冲区溢出。
首先,打开war-ftp 1.65,设置成online状态,然后打开命令行,输入ipconfig,查看本机的ip地址:
![320f31163d11fd299f76b8ff0e4fd152.png](https://i-blog.csdnimg.cn/blog_migrate/e9363b027193bc83939bb5afeb9f484f.jpeg)
![93f9649a519e8514fa20b4c2d6448ac8.png](https://i-blog.csdnimg.cn/blog_migrate/8b1721b670f24155ff816c830dc9bf6c.png)
然后输入ftp -n,并且连接到本机地址:172.16.245.140 21:
![1c9610b17c3a287297b212793bcb9850.png](https://i-blog.csdnimg.cn/blog_migrate/312c52658d973f8ac734f62b39497fe6.png)
然后,分别使用不同长度的用户名进行登录尝试:100个’A’,发现war-ftp 1.65没有崩溃,只是没有成功登录。
![29afd7b2737ce13372b6e8354a23c185.png](https://i-blog.csdnimg.cn/blog_migrate/732e1053ec0c3ac7c3588556063dc674.png)
![55bf793cbdd19d701f1f584a965b9f1a.png](https://i-blog.csdnimg.cn/blog_migrate/608cfaffa246d0853675e8b428c92951.png)
构造1000个’A’进行连接,发现程序会崩溃,我这里程序直接退出了:
![2b9a3dd941852aca2f8b101cdfccaedf.png](https://i-blog.csdnimg.cn/blog_migrate/33c0baed19c29288a1b27dc473178f74.png)
接下来,用cdb进行调试来证明程序崩溃了,重新打开war-ftp,并且使用ftp连接上,输入user ‘A’*1000但是不要回车准备调试。再打开一个cmd窗口,输入cdb -fn war-ftpd.exe进行调试,打开后输入g使程序运行起来:
![c78fed190c13ce110d178e1a96b2f76e.png](https://i-blog.csdnimg.cn/blog_migrate/cfd481dfd39a22a41bd8122f6d0d3a19.png)
![70094f1b2eb483129f6714b5cd594695.png](https://i-blog.csdnimg.cn/blog_migrate/b556e8e8d24c38d060d093b72aa3e7fc.png)
在ftp的命令行页面,输入1000个’A’的用户名和密码回车运行:
![0cd53824545ed526df2d4a85d0c87997.png](https://i-blog.csdnimg.cn/blog_migrate/58750c4345a3518229900ec20a6f89d5.png)
可以观察到:
![a24a4018321d7a2710ba195b97e052a0.png](https://i-blog.csdnimg.cn/blog_migrate/298cd7ee6f8ea81776467701ad9bb3a2.png)
eip的位置全部被A的ASCII码值41填充,用dd esp命令可以查看esp寄存器中的值,也全部被41填充:
![10c4f522c6036c008e6167afaaf93e72.png](https://i-blog.csdnimg.cn/blog_migrate/f97a7672b262512c5690869a8c45ec09.png)
这里war-ftp程序已经无法点击了,我们可以验证这个缓冲区溢出漏洞会导致程序崩溃,而且根据eip和esp全部被41填充,可以通过构造特殊的不重复字符串找到eip和esp被填充的字符串从而找到偏移地址从而构造最后的shellcode来调用系统计算器。
- 通过构造不重复字符串作为用户名来查看偏移地址
重新打开软件和命令行,首先通过给出的perl程序来生成1000个不重复的字符串:
Perl patternCreate.pl 3.txt 1000
![04af407fa5a70b9c60626eaaa22c24e6.png](https://i-blog.csdnimg.cn/blog_migrate/38714204868d4862d209811dbc81d567.png)
利用和上述一样的方法来调试这个程序,截图如下:
利用不重复字符串作为用户名:
![b47531f8e533002bdea0f81690e58655.png](https://i-blog.csdnimg.cn/blog_migrate/6cfd02bb596d1489d2bd9c91420229ab.png)
尝试连接后的调试结果:
![5c66602f58611616748452e581388ded.png](https://i-blog.csdnimg.cn/blog_migrate/15ea76a03d612067f55830097635bdd6.png)
eip、esp和ebp的内容如下:
![ff38fd16416faad00a17a2b07e36a641.png](https://i-blog.csdnimg.cn/blog_migrate/638a3d90d32eee38d284af822ca4d80d.png)
这里我们可以看到eip指向位置的内容为:32714131,esp指向位置的内容为71413471,ebp指向位置的内容为34744133,接下来通过patternOffset.pl来Return Address即eip指向的位置和esp、ebp位置的在1000个字符中的偏移量,我们通过如下命令看到:
![e5416a07d1f9c839b07f397575861fd3.png](https://i-blog.csdnimg.cn/blog_migrate/3330396e1437259e8c27fa47d6de4135.png)
EIP偏移量为485(从0开始),ESP偏移量为493,EBP偏移量为581。可以得到war-ftp1.65的堆栈图为:
![cd10caab244df932f4cff1753baafbd6.png](https://i-blog.csdnimg.cn/blog_migrate/29fcf1d04e328bbf8e9963cf9ce3cc95.jpeg)
- 通过构造字符串来完成最后的攻击程序
这里仿照助教老师使用ESP作为跳转的寄存器,所以我们需要JMP ESP的指令地址,这里助教老师已经给出了地址:JMP ESP:0x7ffa4512。我们要把在网上找到运行计算器的shellcode放在JMP ESP位置。
通过构造字符串,
buffer = "x90"*485
buffer += "x12x45xfax7f"
buffer += "x90"*12
buffer += shellcode
buffer += "x90"*12
最终得到了攻击的Python代码:
![0eff106952a5a4b2cbaedf662d94b040.png](https://i-blog.csdnimg.cn/blog_migrate/6924f339e85fe215602ea9fcbac485c4.png)
执行时记得要打开war-ftp 1.65并连接,执行后的结果是:
![5dd1bd56892ed65a2e76c7d0a2bac394.png](https://i-blog.csdnimg.cn/blog_migrate/78c205a3cfd8511334589082ee30d4ee.jpeg)
五、实验体会与收获
这次实验我遇到了很多的问题:
首先是cdb的Symbol路径,每一次准备调试都报错,于是查了一上午资料才发现助教老师给的视频中也存在这个错误,但是我还是下载好了对应的版本从而解决了这个问题。
其次是调试的步骤,虽然我会一些编译器的调试过程,但是对于这个调试过程却不知怎么进行,一开始输入g之后任何东西都不动了还以为出了问题,后来才知道要先g,然后再提交输入的用户名。
还有最重要的一点也是收获最多的一点就是我学会了如何利用shellcode来构造攻击代码,也进一步深刻理解了函数的寄存器和栈帧结构,也进一步复习了函数的执行过程。
除了上一个收获之外,我还了解了cdb的基本调试指令,认识到了缓冲区溢出漏洞的危害之大,所以我们在日常开发中必须要做好边界检查,而且要认真保护操作系统,只有不断提高系统的安全性,我们才能大规模避免缓冲区溢出漏洞。
更多的收获就是一定要亲手实践才能获得好知识!