20222427 2024-2025-1 《网络与系统攻防技术》实验一实验报告

1.实验内容

(1)本周学习内容

1.学习缓冲区溢出的基本原理。
2.重温栈与堆的概念以及执行流程。
3.逐步熟悉Linux系统对文件的处理流程,掌握基础的汇编与反汇编语言。

(2)本周实验任务

1.手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
2.利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
3.注入一个自己制作的shellcode并运行这段shellcode。

2.实验过程

任务一:直接修改程序机器指令,改变程序执行流程

(1)修改终端名(学号+姓名),下载目标文件pwn1,并且重命名(学号)

(2)对原文件使用反汇编指令,对pwn中的代码进行修改

从这里可以看到main函数调用的是foo函数,如果我们想让函数直接调用getShell,我们要将d7ffff改为getShell的地址“80484ba”对应的补码(804847d-80484ba=-61=0xfffff3c)即可。

(3)使用vi指令以及十六进制编辑器进行修改。


将d7改为c3之后注意输入“:%!xxd -r”转换16进制为原格式以及“:wq”保存修改!

(4)对复制的文件用一次反汇编指令“objdump -d pwn20222427x"

可以发现我们已经修改成功了。

(5)运行一下文件,可以发现shell提示符

任务二:通过构造输入参数,造成BOF攻击,改变程序执行流

(1)从下图可以看出系统给foo函数提供了0x38即56个字节大小的缓冲区,那么我们就可以设计一个字符串,进行缓冲区溢出攻击。

在实验的过程中发现kali并没有自带gdb

所以我们使用指令“sudo apt update” 和 “sudo apt install gdb”进行人工安装gdb。

(2)接下来确认输入字符串哪几个字符会覆盖到返回地址

使用gdb pwn20222427(gdb) r(gdb) info r指令、人为输入1111111122222222333333334444444455555555:

此时EIP的值,是ASCII 5

再次输入(gdb) r(gdb) info r指令、人为输入1111111122222222333333334444444412345678:

可以发现现在的EIP的地址已经变成了0x34333231也就是我们想要的4321。

(3)确认用什么值来覆盖返回地址

getShell的内存地址,通过反汇编时可以看到,即0804847d。

由于我们没法通过键盘输入\x7d\x84\x04\x08这样的16进制值,所以先用指令 perl -e 'print "20222427202224272022242720222427\x7d\x84\x04\x08\x0a"' > input生成包括这样字符串的一个文件。\x0a表示回车,再使用16进制查看指令xxd查看input文件的内容是否如预期。然后将input的输入,通过管道符“|”,作为pwn20222427的输入。

任务三:注入Shellcode并执行

(1)首先进行准备工作

在进行修改堆栈设置之前,要先进行安装execstack,于是用了命令sudo apt-get updatesudo apt-get upgradesudo apt-get install execstack,但会遇到一些问题:

后通过上网查询资料,得知有可能是与镜像有关系,随后进行了几步改动之后成功安装execstack。

接下来进行对堆栈的修改

(2)构造要注入的payload

Linux下有两种基本构造攻击buf的方法:

retaddr+nop+shellcode。

nop+shellcode+retaddr。

因为retaddr在缓冲区的位置是固定的,shellcode要不在它前面,要不在它后面。简单来说缓冲区小就把shellcode放后边,缓冲区大就把shellcode放前边。

本次实验采取的结构为:nop+shellcode+retaddr。

nop一为是了填充,二是作为“着陆区/滑行区”。

我们猜的返回地址只要落在任何一个nop上,自然会滑到我们的shellcode。

接下来我们构造一个payload为perl -e 'print "\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62
\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x90\x4\x3\x2\x1\x00"' > input_shellcode

打开终端注入这段攻击buf:

打开另外一个终端,用gdb调试pwn这个进程

通过设置断点,来查看注入buf的内存地址

输入info r esp查询返回地址,由于shellcode是紧挨着返回地址,所以可以计算出此时的shellcode的地址应为0xbffff3e0,再次修改字符串:

可以发现我们已经成功地完成了攻击!

(3)结合nc模拟远程攻击

该实验中我选用的方案是在同一台主机上装一个Linux系统虚拟机以及其克隆机,可以完美地避免无法连接的问题。

验证是否相连(机1ping机2):

主机1,模拟一个有漏洞的网络服务:

主机2,连接主机1并发送攻击载荷:

3.问题及解决方案

问题1:使用指令ps -ef | grep pwn1发现完全找不到pwn文件的进程。

问题1解决方案:通过询问同学、老师发现在上一步操作中严禁输入回车(对于操作系统来说回车也是一个指令起到中断的效果),否则会完全找不到进程,通过再一次实验避免了这一个问题。

问题2:安装execstack的时候发现老是无法定位软件包,后通过查询资料得以解决。

问题2解决方案:在网上寻找新的镜像,将原先的注释掉,再加入自己找到的新镜像,问题即可解决。

问题3:在第二次进行注入攻击的时候,出现的结果都不尽人意(如下图),无法输出正确的shell。

问题3解决方案:通过与同学的讨论,怀疑是我注入的字符串的内容有误,于是和同学讨论出一个比较正确的字符串作为要注入的payload,随即就输出了正确的结果。

问题4:在进行最后的一个实验中发现Vmware虚拟机中没有VMnet0,无法在桥接模式下联网。

问题4解决方案:重启Vmware虚拟机,其次在编辑中的虚拟网络编辑器中进行还原默认设置,找到了VMnet0。

4.学习感悟、思考等

本次实验是网络与系统攻防技术的第一次实验,在实验之前我也抱着固有的思维,认为应该要先提前准备实验,当我一看到精简的实验题目之后,我的脑海中没有任何的想法,这也是让我无从下手的一部分原因。随即到了实验课的时间,听老师在讲台上讲着相关的原理,这才逐步地清楚我们应该要干什么。但不用想,这肯定是一个陌生且困难的尝试,从什么都不知道,到知道该如何去做,最后是如何成功地完成。随着一步步的操作,遇到的问题也是层出不穷,不断的在网上寻找解决方法,使得我的热情越来越低,效率也越来越慢。在实验的过程中一个'\0a'就花了我长达几个小时的时间,最后还是通过寻求老师以及同学的帮助才得以解决。

在本次实验中,我认识到做实验一定要保持冷静、严谨的态度。每一个问题也许都不是大问题,只需要自己好好检查就可以发现错误,这就要看看自己是否有那个耐心了!不能碰到了问题就无所适从,多看看之前的操作是否出现了错误,花点儿时间在网上查询相关资料,这也是一种学习的好方法。

还有最重要的一点:寻求他人的帮助是提高效率的途径。也许你自己找不到自己哪里出现了错误(认为自己的操作是对的)。这种心态我认为每个人都会有,这个时候让别人看看你的实验过程,也许就会有一些不一样的发现。遇到了问题,问问身边的同学是否也遇到了相关的问题,问问有没有什么方法去解决,这其中花费的时间会远远小于自己在网上查询资料所花费的时间。这让我感受到“一个人的力量一定小于众人的力量”。

参考资料

posted @ 2024-10-07 13:58  20222427夏文韬  阅读(24)  评论(0编辑  收藏  举报