20242801 2024-2025-2 《网络攻防实践》第9次作业
20242801 2024-2025-2 《网络攻防实践》第9次作业
一、实验内容
- 总体任务使pwn1程序执行一个原本不该执行的程序(getshell函数)。
- 通过直接修改可执行文件的代码,改变程序的执行流程,使其执行getshell函数。
- 通过foo函数的漏洞,构造攻击输入字符串,触发getshell函数。
- 制作一个shellcode,使其可以触发getshell函数。
二、实验过程
(一)直接修改程序机器指令
1、更改主机名
由于本次实验有了新要求,要求主机名为自己的姓名拼音。所以我们的第一步是更换主机名,在此使用hostname yuanshaowei,hostname可以暂时更改主机名。

2、备份pwn文件
首先,我们将pwn1文件移动到kali主机中,解压后使用mv pwn1 pwn20242801将pwn1命名后接自己的学号。

然后我们在每次操作pwn文件时,都备份一次。
3、反汇编pwn文件
使用objdump pwn20242801 | more对pwn文件进行反汇编,并通过管道符发送到more方便查看。

通过观察代码我们可以发现main函数调用了foo函数,调用的地址是d7 ff ff ff,如果我们把这个地址换成getshell的地址,那么程序的运行的时候就会自动进行getshell函数中。
下面,我们需要搞清楚如果要跳到getshell函数,d7 ff ff ff应该换成什么。经过查阅资料,我们得知d7 ff ff ff现在是补码而且是小端序,换算后的数值是-29,那么main函数的下一个地址(80484ba)加上这个偏移就是foo函数,即80484ba+ffffffd7=8048491。那么我们计算下getshell的地址和80484ba之间的距离,将其转化为十六进制补码将其填入d7 ff ff ff位置即可。经过计算,这个值应该是c3 ff ff ff。
我们需要下载xxd工具用来修改代码。
xxd 是一个在 Unix 和类 Unix 系统(如 Linux)中常用的命令行工具,它用于创建文件的十六进制转储或者执行相反的操作。
下载好xxd后,使用vim打开备份好的文件,然后定位到d7ff位置,将其修改为c3ff即可。修改后,需要先使用%!xxd -r将数据转换为原格式,再保存退出。


接下来,我们运行pwn程序,可以发现成功执行。

成功执行!
(二)、输入字符串攻击
1、分析汇编代码
我们重新分析下通过objdump命令输出的汇编代码。

可以看到foo函数只分配给输入数据28字节的空间,也就是说当输入数据大于28字节,程序就会异常执行。继续观察,我们可以发现,但输入字符串在第33-36字节处填入getshell函数的地址,程序就会跳转到getshell函数执行。
接下来,我们在kali上安装gdb,并使用gdb调试pwn文件,输入1111111122222222333333334444444498765432,来进一步分析pwn文件的执行。


然后,我们输入info r查看寄存器的值。

可以发现,此时eip寄存器中的值为6789,也就是说我们应该使用小端序输入getshell函数的首地址。
2、编写攻击字符串
我们借助perl语言perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input生成一个包含getshell函数首地址的文件。

然后将其作为pwn文件的输入,执行pwn文件,成功调用了getshell函数,成功!

(三)注入shellcode
1、构造shellcode
Shellcode的原理,简单来说,就是一段可以插入到某些程序或系统中并被执行的代码。它的主要用途是在安全研究中,特别是在开发和利用软件漏洞过程中。
首先,我们需要下载execstack,这个软件可以控制操作系统设置堆栈可执行的权限。我们下载好这个软件之后,像pwn文件设置为堆栈可执行,并关闭随机地址化。


经过查阅相关资料,我们了解到linux有两种构造攻击buf的方法,分别是retaddr+nop+shellcode和nop+shellcode+retaddr。
本次实验我们使用anything+retaddr+nops+shellcode结构,使用如下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语言将其保存到文件中,在之后执行时将其作为输入。

2、测试pwd执行
在构造shellcode时,我们无法确定\x4\x3\x2\x1的取值。那么,我们先将这个字符串注入程序中,观察程序的执行。

然后,我们打开另一个shell,使用ps -ef | grep pwn20242801-3查找pwn的进程号。

pwn的进程号是42137。
接下来,我们使用gdb,输入attach 43137调用该进程。

然后,输入disassemble foo反汇编foo函数,查看ret的地址。

可以看到,ret的地址是80484ae。然后我们在该位置设置一个断点,进行执行程序,触发断点。

然后我们在程序执行到ret位置,查看esp寄存器的值,并查看该地址附近的数据。

3、修改shellcode
我们观察到,如果将返回地址改为ff ff d0 30就可以让程序执行getshell。这样我们就可以确定,将\x1\x2\x3\x4就应该修改为\x30\xd0\xff\xff,我们使用perl改好之后,重新运行程序。


成功获取shell,victory!
三、学习感悟
- 通过本次实验,我了解了缓冲区溢出攻击的基本原理和攻击方法,重新学习本科曾经学过的汇编的知识。之前一直没接触过缓冲区溢出攻击,通过这次实验,也是感觉十分不简单,通过翻阅了许多学长的实验报告,查阅了许多资料,才慢慢明白每一步到底是怎么回事,感觉还是收获了许多。
- 在执行-bash: /proc/sys/kernel/randomize_va_space: 提示权限不够”,经过查阅资料,发现是“sudo”命令不支持重定向。改成sudo bash -c "echo 0>/proc/sys/kernel/randomize_va_space"就可以成功执行。
- 本次学习的完整录屏视频已上传至百度网盘(时间较长文件较大),通过网盘分享的文件:第九次作业
链接: https://pan.baidu.com/s/12fbLX2Pr9JYlLQFuqyN5cQ?pwd=1234 提取码: 1234
浙公网安备 33010602011771号