20212821 2021-2022-2 《网络攻防实践》实践九报告

1.实践内容

1.1实践目标

本次实践的对象是一个名为pwn1的linux可执行文件。

该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。

该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。

1.2三个实践内容如下:

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

1.3实践要求

掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码
掌握反汇编与十六进制编程器
能正确修改机器指令改变程序执行流程
能正确构造payload进行bof攻击

2.实践过程

2.1手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数

首先将下载下来的目标文件复制到kali虚拟机中
然后在kali的终端中使用o命令bjdump -d /home/lvxiuwei/Desktop/pwn1 | more对pwn1文件进行反汇编,如下图所示:

分别找到函数getshell、foo、及main:

可以看到在main函数中执行到call处,EIP应该会指向0x08048491,即foo函数的入口地址,此时的偏移量为0xffffffd7
因此我们应该修改偏移量,使EIP指向getshell的入口地址
经计算,只需将偏移量修改为0xffffffc3,接下来我们进行偏移量的修改:
首先,使用vim打开文件,如下图所示:

打开后,可以看到该文件显示的都为乱码,如下图所示:

因此我们需使用命令“%!xxd”修改为十六进制的形式:

接下来找到我们需要修改的位置:

然后将单个字符逐一使用命令“r”进行修改,如下图所示:

修改完成之后再次使用命令“%!xxd -r”恢复为原来的乱码形式,回复完成之后使用命令“wq”进行保存:

接下来再次运行该程序,并且尝试输入一些命令,可以发现成功跳转到了getshell函数,如下图所示:

2.2利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数

首先通过实验第一部分的反汇编了解程序功能及代码:

可以看到程序正常执行会调用foo函数,而foo函数的功能为对于特定的输入再向屏幕输出这一输入,因此我们可以考虑利用BOF漏洞使用缓冲区溢出攻击触发getshell函数
foo函数执行完成之后,系统会调用的下一条指令的地址为0x080484ba,此地址就是该函数的返回地址
我们只需输入一段设计好的字符串覆盖掉该返回地址,使之变为getshell函数的入口地址就可跳转到getshell函数
使用gdb调试程序运行:

首先输入一段字符串得到输出并查看当前寄存器的内容:

可以看到发生段错误,并且此时EIP内容为0x39393939,对于十进制9999,因此我么确定了覆盖EIP的字符串位置
接下来再次确定存储方式:
使用命令r运行,输入的字符串以及得到的输出如下图所示:

发现程序出现段错误,并且查看当前的EIP寄存器的内容为0x34333231,正好为十进制1234,由此可以确定为小端存储
接下来我们就可以构造特定的输入串了:
我们没法通过键盘输入\x7d\x84\x04\x08这样的16进制值,所以先生成包括这样字符串的一个文件。
键入perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input,如下图所示:

然后使用命令(cat input; cat) | ./pwn1将input的输入,通过管道符“|”,作为pwn1的输入,覆盖返回地址,程序运行结果如下图所示:

由上图可知,我们成功利用BOF漏洞覆盖返回地址,触发了getShell函数。

2.3注入一个自己制作的shellcode并运行这段shellcode

本次实验我们使用的shellcode为:
\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
采用的构造方法为:retaddr+nop+shellcode,将shellode放到缓冲区后边的位置;
前期准备工作:
execstack -s pwn1:将堆栈设为可执行状态
execstack -q pwn1:查看文件pwn1的堆栈是否是可执行状态
more /proc/sys/kernel/randomize_va_space:查看地址随机化的状态
echo "0"> /proc/sys/kernel/randomize_va_space:关闭地址随机化
如下图所示:

准备工作完成之后,首先我们要确定返回地址retaddr:
在终端中运行程序:

之后打开另一个终端,使用如下命令获取pwn1进程的进程号,可知进程号为6533;并且之后使用sudo打开gdb,如下图所示:

之后使用如下命令调试该进程:

之后可以看到该进程的寄存器和堆栈以及其他一些信息,如下图所示:

接下来在foo函数执行完返回mian函数之处设置断点,并且使用命令c继续执行,之后在运行该程序的另一个终端中输入字符串“aaa”之后按下回车,再次回到gdb调试窗口,可以看到程序在断点处停止,并且显示了此时的寄存器信息,上述过程如下图所示:

使用如下命令也可以看到ESP寄存器中的内容:

可知ESP所存储的内容0xbffff4cc指向返回地址0x080484ba,我们要使返回地址为shellcode的入口地址,只需使ESP=0xbffff4cc+0x4=0xbffff4d0;
由之前的实验可知该程序的缓冲区长度为32个字符,故我们使用如下命令构造输入字符串,采用的构造方法为:retaddr+nop+shellcode,如下图所示:

构造完成之后运行,按下回车并使用一些命令来观察是否成功,由上图可知成功运行了注入的shellcode。

3.学习中遇到的问题及解决

  • 问题1: 一开始做实践第三部分的时候对缓冲区溢出攻击的原理不是很了解,导致实验很难进行
  • 问题1解决方案:在网上查找了一些关于缓冲区溢出攻击的讲解之后理解了很多,最后成功进行了实验。

4.实践总结

本次实验基本都是围绕着缓冲区溢出攻击这一网络攻击方式展开的;通过本次实验,我对缓冲区溢出攻击的原理和实现过程都有了一个很好的了解,学到了很多,对网络攻防也有了更进一步的认识。

参考资料

《网络攻防技术与实践》

posted @ 2022-05-13 11:34  ~嘉然今天吃什么  阅读(92)  评论(0编辑  收藏  举报