20192405张纹豪 2021-2022-2 《网络与系统攻防技术》实验一实验报告
20192405张纹豪 2021-2022-2 《网络与系统攻防技术》实验一实验报告
1.实验内容
手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
注入一个自己制作的shellcode并运行这段shellcode。
该可执行文件有如下特征:
main调用foo函数,foo函数会简单回显任何用户输入的字符串。
该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode
2.实验过程
方案一:手工修改
(1)首先通过objdump反汇编查看pwn文件中函数的地址
可知:
(2)查看main函数中调用foo函数的代码
80484b5: e8 d7 ff ff ff ;;call 8048491
80484ba: b8 00 00 00 00 ;;mov $0x0,%eax
(3)根据地址信息计算新的调用地址
main函数调用foo函数分析:
执行到call 8048491 行时发生了调用,此时指令寄存器EIP中存放的信息为0x080484ba。因此有如下计算公式
foo地址 - [EIP] = call指令后的数据
0x08048491 - 0x080484ba = 0x-29
0x-29的补码是d7 ff ff ff,以小端序显示
如果要修改为调用getShell函数,则有如下计算公式:
getShell地址 - [EIP] = call指令后的数据
0x0804847d - 0x080484ba = 0x-3d
0x-3d的补码是ff ff ff c3,小端序为c3 ff ff ff
(3)修改文件内容
使用vi编辑器的十六进制显示模式:%!xxd
,查找d7 ff ff ff
,将其修改为c3 ff ff ff
方案二:构造字符串
(1)查看foo函数的Bof漏洞并计算缓冲区空间
由第一步可以看出:
08048491
8048491: 55 ;;push %ebp
8048492: 89 e5 ;;mov %esp,%ebp
8048494: 83 ec 38 ;;sub $0x38,%esp
8048497: 8d 45 e4 ;;lea -0x1c(%ebp),%eax
804849a: 89 04 24 ;;mov %eax,(%esp)
指令sub $0x38,%esp
表示开辟0x38的堆栈空间,lea -0x1c(%ebp),%eax
表示将-0x1c的空间赋给临时变量(用于存储输入)。由进制转换可知,38(h) = 56(d), 1c(h) = 28(d),所以缓冲区大小为28个字符
下载gdb并安装
(2)测试返回地址所在的溢出位置
使用gdb调试程序,查看溢出的字段对EIP的影响
已知getShell的内存地址为:0804847d
由此可知我们需要构造的字符串为"11111111222222223333333344444444\x7d\x84\x04\x08\x0a"('0a'表示回车)
由于该字符串无法直接输入,接下来我们需要使用Perl语言生成一个包含这样字符串的文件,来构造输入值
然后我们将input的输入,通过管道符“|”,作为pwn1的输入,实现BOF攻击
方案三:注入shellcode
由于我们要根据程序运行时所分配的地址进行攻击,即更改返回值使其运行我们所编写的shellcode,所以在实验开始前我们必须关闭地址随机化
retaddr+nops+shellcode结构来攻击buf,其中nop为填充字节所用的空指令,机器码为90,retaddr即跳转地址。先使用\x4\x3\x2\x1代替我们多编写的shellcode的地址
找到进程号18639
(2)使用GDB调试检测retaddr的内容
打开另一个终端查看pwn这个进程
使用gdb调试这个进程:
使用disassemble foo
将foo函数反汇编,然后在foo函数的ret位置设置断点break *0x080484ae
, 输入命令c
继续执行,然后在第一个终端按回车。命令info r esp
查看esp的内容,命令x/16x 0xffffd15c
查看内存信息,命令x/16x 0xffffd13c
查看文件输入信息
使用x/16x 0xbffff53c查看其存放内容,看到了01020304,就是返回地址的位置。
最后只需要将之前的\x4\x3\x2\x1改为我们希望跳转的shellcode地址即可
4.问题及思考
首先,因为下载了32位的kali,导致apt安装gdb出现问题,尝试解决未果,网上找解决方法失败,转而换源。
再者,改完16进制忘记改回来,导致出现奇怪bug。
其次,在完成第三部分的实践时,没有关闭地址随机化,导致每次找到的内存地址都不一样,一直得不到自己想要的结果。
思考:
作为本学期网络攻防课的第一次实验,目的是结合逆向技术实现缓冲区溢出攻击。我开始从头学习汇编语言,也再次使用kali Linux在这次实验中也遇到了很多问题,但是在老师和同学的帮助下我还是一一解决了这些问题,还在linux指令操作上面也实现了自我的进步。通过这次实验,我也意识到了学好网络攻防课的核心在于实践,虽然老师课上讲的东西很多,但是实际操作还是会有各种各样的问题,我会继续努力,把实践与理论结合。