20242422 2026-2027-1 《网络与系统攻防技术》实验一实验报告

20242422 2026-2027-1 《网络与系统攻防技术》实验一实验报告

1. 基础知识

本次实验为缓冲区溢出基础实验,主要涉及 Linux 下 32 位 ELF 可执行文件、栈结构、函数调用栈帧原理。

  1. 缓冲区溢出原理:程序使用不安全函数gets()读取输入,未对输入长度做校验,超出缓冲区的数据会覆盖栈上的 ebp 以及函数返回地址 ret。当函数执行 ret 指令时,CPU 会跳转到被覆盖的地址执行代码。
  2. objdump 工具:二进制反汇编工具,查看程序汇编指令,获取函数入口地址。
  3. xxd:十六进制查看与转换工具,可以将二进制文件转为十六进制文本进行修改,再还原回二进制程序。
  4. GDB:程序调试器,用于断点调试、查看寄存器、内存地址,获取栈地址、偏移量。
  5. ASLR:地址空间布局随机化,系统安全保护机制,开启时栈地址每次运行都会变化,实验需要临时关闭。
  6. 小端序:x86 架构存储多字节数据时,低位字节放在低地址,构造 payload 地址时需要按小端序排列。

2. 实验内容

任务一:直接修改机器指令,改变执行流程
任务二:BOF 攻击,覆盖返回地址
任务三:注入 Shellcode,运行任意代码
实验环境:VMware 虚拟机,Kali Linux 系统,32 位 ELF 程序。

3. 实验过程

任务一:静态修改二进制文件

  1. 使用objdump -d pwn1_20242422 | grep -A20 -B10 getShell命令反汇编,获取 getShell 函数入口地址0804847d,截图保存。
    alt text
  2. 查看 main 函数汇编代码,main 函数会调用 foo 函数,foo 函数执行完成后 ret 返回 main。目标是修改 foo 函数的返回地址,替换为 getShell 入口地址。
    alt text
  3. 使用 xxd 将 pwn1 二进制转为十六进制文本pwn1.hex,使用 nano 编辑器打开十六进制文件,找到 foo 函数 ret 对应的返回地址位置,将原有返回地址修改为 getShell 的地址(小端序)。
    alt text
    alt text
  4. 执行xxd -r pwn1.hex > pwn1_mod,将十六进制文件还原为新二进制文件;chmod +x pwn1_mod赋予执行权限,运行./pwn1_mod,成功弹出 shell。
    alt text

任务二:栈溢出跳转 getShell

  1. 分析 foo 函数汇编,foo 函数内部调用危险函数 gets,存在缓冲区溢出漏洞。计算缓冲区到返回地址的偏移长度。
  2. 构造 payload:填充字符(A)填满缓冲区 + ebp,后面拼接 getShell 函数地址(小端序)。
  3. 将 payload 输入给 pwn1 程序,覆盖栈上返回地址。当 foo 函数执行 ret 时,CPU 读取被篡改的返回地址,跳转到 getShell 函数,成功获取 shell。

任务三:Shellcode 注入执行

  1. 执行sudo sysctl -w kernel.randomize_va_space=0关闭系统 ASLR 地址随机化保护,保证栈地址固定。
  2. 使用 GDB 调试gdb ./pwn1_20242422,在 foo 函数断点,运行程序,获取栈上 esp 地址。
    alt text
  3. 编写 Python exp 脚本,构造 payload:填充 A 字符至返回地址偏移,将返回地址改为栈上 shellcode 起始地址,后面拼接 32 位 Linux 系统调用 shellcode。
    alt text
  4. 运行 exp 脚本,将 payload 输入程序,触发栈溢出,程序跳转到栈中 shellcode,执行 shellcode,获取 shell。
    alt text

4. 问题及解决方案

  • 问题 1:VMware 虚拟机,宿主机和 Kali 之间无法直接拖拽文件,无法把 pwn1 二进制传入虚拟机。
  • 解决方案:改用 Python 简易 HTTP 服务传输文件。在宿主机开启 http 服务,Kali 虚拟机使用 wget 命令下载 pwn1 文件。
  • 问题 2:虚拟机鼠标卡顿,鼠标指针几乎看不清。
  • 解决方案:安装 VMware Tools,虚拟机设置调整鼠标缩放;临时切换虚拟机独占模式。
  • 问题 3:修改完十六进制文件,xxd 还原二进制后程序无法运行。
  • 解决方案:修改十六进制时,严格核对地址位置,不要改动其他无关字节;还原二进制后,必须执行 chmod +x 添加可执行权限。
  • 问题 4:GDB 调试获取地址,直接在 gdb 内执行 shell 命令,命令报错。
  • 解决方案:区分 GDB 内命令和系统 bash 命令,shell 命令需要在 GDB 外部终端执行;gdb 内部使用 run、break、x 等调试指令。
  • 问题 5:payload 发送后程序没有反应,无法触发溢出,或者报段错误。
  • 解决方案:缓冲区偏移量计算错误;重新用 pattern_create、pattern_offset 精确计算溢出偏移;检查地址是否写成大端序,x86 需要小端序。
  • 问题 6:ASLR 开启,每次调试栈地址都变化,shellcode 无法稳定执行。
  • 解决方案:使用 sysctl 命令临时关闭内核 ASLR 随机化。

5. 学习感悟、思考等

本次缓冲区溢出实验,直观理解了程序栈帧、函数调用和返回地址的底层原理。gets()这类不安全函数不限制输入长度,是栈溢出漏洞的根源。
实验一共三个任务,从静态修改程序,到利用溢出跳转已有函数,最后注入 shellcode 执行自定义代码,层层递进。实验过程中遇到虚拟机文件传输、地址大小端、ASLR 保护、偏移量计算等问题,在排查问题时加深了对漏洞原理、操作系统内存保护机制的理解。
同时也认识到缓冲区溢出漏洞危害巨大,现代操作系统通过 ASLR、栈保护等机制缓解溢出攻击。开发程序时禁止使用 gets、strcpy 等危险函数,做好输入长度校验,从源码层面防止缓冲区溢出。

参考资料

posted @ 2026-10-12 10:01  20242422liuxiang  阅读(10)  评论(0)    收藏  举报