20212416 2023-2024-2 《网络与系统攻防技术》实验一实验报告
1. 实验内容
-
通过三个实践内容,运行linux可执行文件pwn1中的getShell片段。
-
三个实践内容如下:
- 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
- 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
- 注入一个自己制作的shellcode并运行这段shellcode。
-
三个实践内容分别对应以下几种思路:
- 运行原本不可访问的代码片段
- 强行修改程序执行流
- 以及注入运行任意代码
2. 实验过程
2.1 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
-
- 基础知识掌握:掌握PUSH,CALL,NOP, RET等汇编指令的机器码
- 基础知识掌握:掌握PUSH,CALL,NOP, RET等汇编指令的机器码
-
- 下载目标文件pwn1,反汇编
- 下载目标文件pwn1,反汇编
-
- 解读反汇编结果
- 对应机器指令为"e8 d7 ff ff ff",e8即跳转之意,将调用位于地址8048491(EIP(80484ba) +d7ffffff)处的foo函数
- 所以,若想使得程序跳转至位于地址804847d处的getShell函数,就需要把d7ffffff改为c3ffffff。
- 解读反汇编结果
-
- 修改可执行文件
-
对pwn1进行备份,再进行修改
-
打开编辑器,将显示模式切换为16进制模式(:%!xxd),查找要修改的内容(/e8d7)并进行修改(/e8c3):
- 修改前:
- 修改后:
- 修改前:
-
转换16进制为原格式(:%!xxd -r)并存盘退出vi(:wq)
-
再反汇编看一下,call指令是否正确调用getShell
2.2 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
-
- 反汇编,了解程序的基本功能
- 由下图可知,< foo >函数缓冲区长度为 0x1c(28)字节,该函数存在Buffer overflow漏洞,超出部分会造成溢出,我们的目标是覆盖返回地址
- call调用foo,同时在堆栈上压上返回地址值:0x80484ba
-
- 确认输入字符串哪几个字符会覆盖到返回地址
-
EIP的值为ASCII “5555”
-
EIP的值为ASCII “1234”
-
以上的两个尝试说明,“5555”、"1234"这四个数最终会覆盖到堆栈上的返回地址,进而CPU会尝试运行这个位置的代码。那只要把这四个字符替换为 getShell 的内存地址,输给pwn1,pwn1就会运行getShell。
-
- 确认用什么值来覆盖返回地址
- getShell的内存地址,通过反汇编时可以看到,即0804847d。对比之前 eip 0x34333231 0x34333231 ,正确应用输入 11111111222222223333333344444444\x7d\x84\x04\x08
- 生成包含getShell的内存地址的input文件并检查生成文件是否正确
- 将input的输入,通过管道符"|",作为pwn1的输入
成功触发getShell,输入"ls"执行结果正确
2.3 注入一个自己制作的shellcode并运行这段shellcode。
-
- 修改相关设置
- 设置堆栈可执行并查询文件的堆栈是否可执行
- 由于关闭地址随机化需要root权限,我这里是直接打开了root权限下的终端来修改设置
-
- 构造要注入的payload
- 确定构造攻击buf的方法:anything+retaddr+nops+shellcode
- 确定注入payload覆盖到堆栈上的返回地址的位置
- 打开一个终端创建并注入攻击buf
- 再开另外一个终端,找到pwn1的进程号是:200011,用gdb来调试pwn1这个进程。
- 通过设置断点,来查看注入buf的内存地址
- 查询esp中存储的地址,到那去找找shellcode和返回地址的大致位置,并发现返回地址占位也正确
- 我决定将返回地址设为0xffffcff0(0x01020304所在的地址往后数4位)
注入成功
- 打开一个终端创建并注入攻击buf
3.问题及解决方案
-
问题1:kali虚拟机连不上网
-
问题1解决方案:将虚拟机的网络连接方式改为桥接模式
-
问题2:kali虚拟机无法安装gdb调试器
- 安装gdb调试器时显示:Unable to locate package
-
问题2解决方案:在sources.list文件中补充、更新kali存储库,详情见参考连接
https://blog.csdn.net/weixin_43729943/article/details/104221462 -
问题3:payload注入失败,程序没有正确触发shellcode,只是一直报告pwn1崩溃
- 虽然在进行实践三时按照步骤关闭了地址随机化,但在进行payload注入时esp的地址还是会改变,猜想可能是因为出于保护机制,虚拟机待机之后地址随机化又重置了?
-
问题3解决方案:在进行payload注入前再关闭一次地址随机化
4.学习感悟、思考等
- 基础知识的牢固程度影响解决问题的效率
- 刚刚的问题1,虽然我只用了两行文字就结束了这个问题,实际上我花了可能有两天的时间来解决。网络上提供了很多种可能的错因,包括网络连接方式、使用国外镜像站点使得下载更新慢、DNS服务器列表问题等。我连桥接模式和专用主机模式的区别都一知半解,桥接模式设置成哪块网卡对联网有没有影响都不知道,穷举般的试错当然耗费时间。
- 当你走头无路时,不妨从头开始再做一遍
- 刚刚的问题3,我一直在怀疑是不是自己算出来的返回地址有误(因为我的esp里存储的地址和老师的不一样),反反复复算了几遍都是一样的结果。最后发现并不是地址计算的问题,束手无策时,从头来一遍也许是寻找新思路的好办法。