20242409 2025-2026-1 《网络与系统攻防技术》实验1实验报告
网络攻防与实践
实验指导书
题目: 实践一 逆向破解与BOF
学生姓名: 伍宸崟
所在系别: 网络空间安全系
专 业: 网络空间安全专业
学 号: 20242409
指导教师: 王志强
2026 年 9月
目 录
1 基础知识 3
1.1汇编指令及其机器码 3
1.2 32位Linux程序与ELF可执行文件 3
1.3栈帧、缓冲区溢出 BOF 原理 3
1.4汇编指令及其机器码 3
1.5Linux 缓冲区溢出保护机制 3
2 实验内容及实验原理 4
2.1实践目标 4
2.2实验环境与工具 4
3 实验过程 4
3.1前置过程 4
3.2任务一:修改call指令的相对偏移,让main直接调用getShell 5
3.2.1查看ELF段信息 5
3.2.2反汇编,来确定具体的需要修改的虚拟地址 6
3.2.3验证结果 7
3.2.4运行验证 7
3.3任务二利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数 7
3.3.1重启后重新关闭ASLR并且验证是否关闭 7
3.3.2找到原版程序并且添加执行权限 7
3.3.3反汇编并且提取getshell函数的入口地址 8
3.3.4查看foo函数汇编并且生成payload 8
3.3.5执行溢出攻击,获取shell 8
3.4任务三注入一个自己制作的shellcode并运行这段shellcode 9
3.4.1检查程序NX保护 9
4 实验问题以及解决方法 9
3.4.2准备shellcode 9
3.4.3执行注入攻击 9
4问题及解决方案 10
5.学习感悟、思考 11
6.参考资料 11
1 基础知识
1.1汇编指令及其机器码
NOP:0x90空指令,不执行任何操作,用于NOP雪橇填充
CMP:常用0x39、0x3B比较操作,做减法,只修改标志位不修改寄存器
JE:0x74 相等则跳转,ZF 标志位为1跳转
JNE: 0x75 不相等则跳转,ZF 标志位为0跳转
JMP:0xEB 无条件跳转,短跳转机器码0xEB,长跳转根据寻址不同变化
1.2 32位Linux程序与ELF可执行文件
ELF文件是Linux可执行程序格式,.text段存放在程序汇编机器指令中,即只读可执行,程序运行则加载到虚拟内存。
objdump -d:反汇编工具,把二进制机器码翻译成AT&T格式汇编,查看函数地址、call/jmp等指令。
call指令格式:e8偏移;CPU执行call时,EIP等于下一条指令的虚拟地址,EIP加上补码偏移得到目标函数地址。偏移是补码形式。
1.3 栈帧、缓冲区溢出BOF原理
函数调用发生时,栈帧结构:局部缓冲区→保存的EBP栈基址 → 返回地址 RET。 ret指令等价于pop % eip,函数执行完毕,从栈取出返回地址赋值 EIP,回到调用处继续执行。BOF缓冲区溢出:不安全函数gets () 不做输入长度校验,超长输入覆盖缓冲区,依次覆盖保存 EBP,最后覆盖返回地址;ret执行时 EIP 被劫持,程序跳转到攻击者指定地址。x8632为小端字节序:4字节虚拟地址,低字节存放在内存低地址,构造payload时地址字节需要逆序。
1.4 Shellcode与Payload、NOP雪橇
Shellcode:可直接执行的原始机器码,本实验为execve ("/bin/sh"),作用获取交互式 shell。 Payload:完整攻击载荷,由填充字节、返回地址、NOP、shellcode组合而成。 NOP雪橇(0x90):大量 NOP空指令;只要 EIP 跳到任意一条NOP,CPU顺序向下执行,滑行到后面shellcode,降低地址猜测难度。
1.5 Linux缓冲区溢出保护机制
NX/DEP:栈内存标记不可执行,禁止栈上shellcode运行;本实验使用 execstack -s关闭。 ASLR 地址随机化:栈、库每次运行虚拟地址随机;echo 0 > /proc/sys/kernel/randomize_va_space关闭。 StackCanary金丝雀:栈插入随机校验值,溢出篡改直接终止程序;本实验 pwn1 编译时已经关闭该保护。
2.实验内容
2.1 实践目标
实验对象:32位Linux ELF可执行文件pwn1_学号。程序正常流程:main调用foo函数,foo接收用户输入字符串并回显;程序内置getShell ()函数,该函数可以输出可用shell,正常代码路径不会执行getShell。 完成三项递进任务:
任务一:手工修改ELF可执行文件机器指令,修改call指令偏移,静态改变程序执行流程,直接调用getShell;不利用输入漏洞,直接修改二进制文件。
任务二:利用foo函数gets() 造成的BOF缓冲区溢出漏洞,构造输入 payload,栈上覆盖返回地址,劫持EIP跳转到程序已有的getShell函数。
任务三:关闭系统防护,构造RNS模式payload,注入自定义shellcode,执行注入的机器指令,获取shell。
2.2 实验环境与工具
环境:32 位Kali Linux;关闭ASLR;设置栈可执行。使用工具:objdump反汇编,vi+xxd十六进制编辑器,gdb调试器,perl生成二进制payload,execstack修改ELF栈属性。
3.实验过程
3.1前置过程
目的:关闭ASLR地址随机化,确认目标程序符号与函数地址

虚拟机重启后ASLR会自动开启,切换root权限执行命令关闭地址空间随机化,使用cat查看配置,返回0代表ASLR关闭成功,保证本次实验内存地址固定。


使用objdump反汇编原始程序,定位foo函数、getShell函数地址。观察到080484b5处指令为e8 d7 ff ff ff call 8048491
3.2任务一:修改call指令的相对偏移,让main直接调用getShell
3.2.1查看ELF段信息
执行命令“readelf -S pwn1_task1_20242409”来确认.text代码段的具体位置


3.2.2反汇编,来确定具体的需要修改的虚拟地址
使用radare2来打开二进制文件,移动到i需改地址后写入机器码,从而修改。

3.2.3验证结果

3.2.4运行验证

3.3任务二利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数
因为在实验课上由于下载等繁琐的事件延误了太多时间所以从任务二开始重新开启虚拟机进行试验
3.3.1重启后重新关闭ASLR并且验证是否关闭

3.3.2找到原版程序并且添加执行权限

3.3.3反汇编并且提取getshell函数的入口地址
得到getshell地址为0804847d
32位小端序反转为:\x7d\x84\x04\x08

3.3.4查看foo函数汇编并且生成payload


3.3.5执行溢出攻击,获取shell

执行命令注入后程序接收溢出输入后跳转到getshell函数,成功获取shell,执行whoami输入root,证明缓冲区溢出攻击成功。末尾出现的段错误是shell退出后原程序继续执行产生不代表攻击失败。
3.4任务三注入一个自己制作的shellcode并运行这段shellcode
3.4.1检查程序NX保护

无输出证明NX关闭,栈是可执行,可以注入shellcode
3.4.2准备shellcode
Payload的设计思路:32A+指向NOP雪橇区域的栈地址+100个NOP+shellcode

3.4.3执行注入攻击
使用env -i清空环境变量,消除环境变量对栈地址的干扰,固定栈空间布局;将Python生成的二进制payload通过管道输入程序pwn1_20242409,触发缓冲区溢出;
程序运行后出现segmentation fault段错误;执行dmesg | tail查看内核崩溃日志。日志显示指令指针ip成功跳转到NOP雪橇区域,证明返回地址覆盖成功。程序崩溃原因为 NX 保护开启,栈内存标记为不可执行,CPU无法执行栈上注入的shellcode,无法弹出shell。本次实验验证缓冲区溢出原理,同时验证 NX 内存保护机制能够防御栈上shellcode注入攻击。

4. 问题及解决方案
问题1:最开始构造BOF的Payload,搞错栈偏移,误以为缓冲区+ebp一共28字节,payload长度不对,程序直接段错误。
问题1解决方案:回头仔细看foo函数汇编lea -0x1c(%ebp),%eax,算出缓冲区28字节,加上4字节ebp,返回地址偏移一共32字节,修正payload填充长度,任务二攻击成功。
问题2:直接固定栈地址做shellcode注入,总是段错误,就算关闭ASLR也不稳定。
问题2解决方案:查阅资料了解到终端环境变量会带来栈地址偏移,使用env -i清空环境变量,固定栈内存布局,提高NOP雪橇命中概率。
问题3:shellcode注入时,dmesg看到ip已经跳到NOP区域,但依旧段错误拿不到shell。
问题3解决方案:查看dmesg错误码为error 7,确认程序NX保护开启,栈内存禁止执行代码。受实验二进制本身限制,无法直接运行栈上shellcode,完成原理层面验证。
5.学习感悟、思考
这次pwn缓冲区溢出实验,一共做了三项任务:手动修改二进制文件改变程序流程、利用缓冲区溢出劫持返回地址,还有注入shellcode。做完之后,我才对32位Linux程序的栈结构、函数调用以及缓冲区溢出漏洞有了直观的认识,不再只是课本上抽象的文字。
缓冲区溢出本质就是程序使用了不安全函数,没有对输入长度做检查,攻击者借此改写栈上数据,改变程序原本的执行路径。实验里我也接触到NOP雪橇、shellcode、ASLR和NX保护这些概念,切身感受到操作系统自带的安全机制,能够有效缓解传统栈溢出攻击。
这次实验也让我体会到,攻防实操对细节要求很高。偏移量计算、字节序、二进制payload输出、虚拟机环境配置,随便哪一步出错,实验就无法得到预期结果。学习这些攻击原理,并不是为了实施攻击,而是理解漏洞的危害,学会如何防御。后续写代码的时候,我会避开gets这类危险函数,做好输入长度校验,从代码源头减少缓冲区溢出这类漏洞,养成安全编码的习惯。
6.参考资料
1.NetSec/ExpGuides/0x12_MAL_Exp1逆向与Bof基础.md(ExpGuides/0x12_MAL_Exp1逆向与Bof基础.md · wildlinux/NetSec - Gitee.com)
2.豆包部分文本语言润色以及问题咨询( https://www.doubao.com/chat/38444442153521922?channel=LwxSh )
3.课程PPT(第2章 系统攻防之缓冲区溢出和shellcode-new-2)

浙公网安备 33010602011771号