当前位置: 首页 > news >正文

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

一、实验内容

本周围绕 Linux 可执行文件 pwn1 的缓冲区溢出(BOF)漏洞与 shellcode 注入展开学习,核心是通过三种技术手段篡改程序执行流程,触发原本不可运行的 getShell 函数或自定义 shellcode。具体包括:手动修改可执行文件的机器指令,直接将 main 函数调用目标从 foo 改为 getShell;利用 foo 函数的 BOF 漏洞,构造攻击字符串覆盖返回地址,间接触发 getShell;在关闭系统防护机制后,注入自定义 shellcode 并实现其运行,最终获取交互式 Shell。

整个学习过程不仅涉及汇编指令、栈结构等底层知识,还需熟练使用 gdb 调试、vi 十六进制编辑、patchelf 等工具,理解小端字节序、地址随机化、堆栈权限等关键概念。

二、实验过程

1、直接修改程序机器指令,改变程序执行流程

(1)下载目标文件pwn1,反汇编分析关键代码:

首先获取目标文件 pwn1 并进行反汇编,重点分析 main、foo 与 getShell 三个函数的地址及调用关系。反汇编结果显示,getShell 函数起始地址为 0x0804847d,foo 函数起始地址为 0x08048491,main 函数中调用 foo 函数的指令位于地址 0x080484b5,对应的机器指令为 “e8 d7 ff ff ff”。

其中,“e8” 为调用指令(call)的操作码,后续的 “d7 ff ff ff” 是相对偏移量(补码形式,对应十进制 - 41)。根据 call 指令的执行逻辑,CPU 会将当前指令下一条地址(0x080484ba)与该偏移量相加,得到目标函数地址(0x080484ba - 0x29 = 0x08048491),即 foo 函数地址。若要让 main 函数调用 getShell,需将该偏移量修改为 “getShell 地址 - 0x080484ba” 对应的补码。通过计算,0x0804847d - 0x080484ba = -0x3d,其补码为 “c3 ff ff ff”。

(2)修改可执行文件,将其中的call指令的目标地址由d7ffffff变为c3ffffff

1)为避免破坏原文件,先复制 pwn1 生成新文件 pwn2311,使用vi编辑它:

cp pwn20232311 pwn2311

vi pwn2311

2)将显示模式转换为16进制模式,便于定位和修改机器指令:%!xxd

屏幕截图 2025-10-08 081622

3)搜索目标指令 “e8 d7”,找到 main 函数中调用 foo 的机器指令位置,将偏移量部分的 “d7” 修改为 “c3”屏幕截图 2025-10-08 081808

屏幕截图 2025-10-08 081729

4)输入:%!xxd -r将十六进制格式还原为可执行文件格式,保存并退出 vi,再反汇编看一下call指令已经正确调用getshell

屏幕截图 2025-10-08 081959

屏幕截图 2025-10-08 082056

5)运行修改后的文件,成功获取 Shell 提示符,表明程序执行流程已成功指向 getShell 函数

屏幕截图 2025-10-08 082147

2、通过构造输入参数,造成BOF攻击,改变程序执行流

(1)反汇编,了解程序的基本功能,分析漏洞函数

重新反汇编 pwn1,聚焦 foo 函数的内存操作逻辑。foo 函数中通过 “sub $0x38, % esp” 分配栈空间,再通过 “lea -0x1c (% ebp), % eax” 将缓冲区起始地址传入 gets 函数。由于 gets 函数无输入长度限制,而缓冲区仅预留 28 字节(0x1c)空间,当输入字符串长度超过 28 字节时,多余数据会覆盖栈中后续存储的 ebp 寄存器值及函数返回地址,从而引发 BOF 漏洞。

同时,main 函数调用 foo 函数时,会将返回地址(0x080484ba)压入栈中,该地址正是后续攻击需覆盖的关键目标。

屏幕截图 2025-10-08 082804

(2)确认输入字符串哪几个字符会覆盖到返回地址

先给pwn2023211提权

屏幕截图 2025-10-08 084851

进行确认哪几个字符会覆盖到返回地址,启动 gdb 调试 pwn1,运行程序并输入测试字符串1111111122222222333333334444444455555555,程序因内存访问错误(SIGSEGV)崩溃,查看寄存器状态(info r),发现 eip 寄存器值为 0x35353535(对应字符 “5” 的 ASCII 码),说明第 33-36 字节的输入覆盖了返回地址;

再次测试,输入1111111122222222333333334444444412345678,崩溃时 eip 值为 0x34333231(对应字符 “1234”),进一步确认输入字符串的第 33-36 字节会覆盖栈中的返回地址。

屏幕截图 2025-10-08 084928

屏幕截图 2025-10-08 084939

(3)确认用什么值来覆盖返回地址

getShell的内存地址,通过反汇编时可以看到,即0804847d。

接下来要确认下字节序,简单说是输入11111111222222223333333344444444\x08\x04\x84\x7d,还是输入11111111222222223333333344444444\x7d\x84\x04\x08。

屏幕截图 2025-10-08 085036

对比之前eip 0x34333231 0x34333231,正确应用输入 11111111222222223333333344444444\x7d\x84\x04\x08。

(4)构造输入字符串

由为我们没法通过键盘输入\x7d\x84\x04\x08这样的16进制值,所以先利用 perl 语言生成包含攻击字符串的文件。其中,前 32 字节为填充字符,第 33-36 字节为反转后的 getShell 地址,最后 “\x0a” 为换行符,用于触发 gets 函数读取结束。

屏幕截图 2025-10-08 085053

使用16进制查看指令xxd查看input文件的内容如同预期。

屏幕截图 2025-10-08 085104

将input的输入,通过管道符“|”,作为pwn20232311的输入。达到预期成果。

屏幕截图 2025-10-08 085113

4、注入Shellcode并执行

shellcode就是一段机器指令(code)通常这段机器指令的目的是为获取一个交互式的shell

(1)准备工作,修改一些设置:

设置堆栈可执行并验证

关闭地址随机化,避免 shellcode 地址被随机化导致无法定位

(2)构造要注入的payload。

采用 “填充字符 + 覆盖返回地址 + NOP sled + shellcode” 的 payload 结构,其中:填充字符:32 字节,用于填满缓冲区并覆盖ebp;覆盖返回地址:需设置为 NOP sled 区域的地址,确保 CPU 执行到该地址时能滑入 shellcode;NOP sled:多个 “\x90”(NOP 指令),用于提高 shellcode 地址命中概率;shellcode:自定义的 Shell 获取指令序列。

初步生成 payload 文件:下面最后的\x4\x3\x2\x1将覆盖到堆栈上的返回地址的位置。我们得把它改为这段shellcode的地址。现在要确定\x4\x3\x2\x1到底该填什么。

1)打开一个终端注入攻击buf:

2)再开另外一个终端,先找到进程号:

3)启动gdb调试这个进程,通过设置断点,来查看注入buf的内存地址

4)反汇编 foo 函数找到返回指令(ret)地址(0x080484ae),设置断点:break *0x080484ae;在第一个终端中按下回车,触发断点,查看栈布局(x/16x esp),找到临时占位地址“\x01\x02\x03\x04”,确定其相邻的 NOP 区域地址

5)可以找到01020304了,就是返回地址的位置。shellcode就挨着,所以地址是 0xffffd440

6)将返回地址改为0xffffd440,使用16进制查看指令xxd查看文件的内容如同预期。并且也能正确体现shellcode。

三、问题分析

1、问题1:

将显示模式切换为16进制模式时 :%!xxd 返回是command not found :xxd。并且执行sudo apt install xxd后依然报错。

问题1解决方案:查阅资料得知是默认的 Kali 官方源在当前网络环境中不稳定或版本不同步。于是便更换为国内的 Kali 镜像源并导入缺少的阿里云 Kali 源的 GPG 验证公钥。之后就可以顺利安装了

2、问题2:

按照常规方法尝试使用 execstack 工具设置堆栈可执行时,发现系统中未安装该工具,且通过 apt 安装时提示 “无法定位软件包 prelink”(execstack 依赖 prelink),导致堆栈权限设置受阻。

问题2解决方案:查阅资料后,选择使用功能类似且更易获取的 patchelf 工具替代 execstack。通过sudo apt install patchelf安装工具后,执行patchelf --set-execstack ~/Desktop/pwn4成功将 pwn4 的堆栈设置为可执行,满足实验需求。上文中有体现。

四、学习感悟

这次实验让我对网络攻防的底层原理有了更直观的认识,不再是停留在理论层面的 “缓冲区溢出”“shellcode” 等概念,而是真正动手操作时感受到每一个字节、每一条指令的重要性。比如修改机器指令时,偏移量的计算错误会导致程序直接崩溃;构造 BOF 攻击时,返回地址的字节序搞反会让攻击完全失效,这些细节让我明白攻防技术需要极致的严谨。

另外,工具的使用也是本次学习的重要收获。从 gdb 调试定位漏洞、vi 编辑二进制文件,到 perl 生成攻击 payload,每一款工具都有其独特作用,熟练掌握它们是开展攻防实验的基础。遇到工具安装问题时,通过查找资料更换替代工具(如 patchelf 替代 execstack),也锻炼了我的问题解决能力,让我明白灵活变通在技术实践中的重要性。

http://www.hskmm.com/?act=detail&tid=29165

相关文章:

  • 你的认知模式,决定了你的人生高度
  • 在Typora中数学公式无法显示问题
  • 洛谷个人主页
  • 原码、反码、补码
  • C++ - 从字符串中提取一个数的若干种写法
  • ABC 日志
  • 251012
  • 如何在UE中创建动态枚举
  • 能连上 GitHub(SSH 验证成功),却 push 失败?常见原因与逐步解决方案 - 详解
  • 换根dp的一个trick
  • 搭建SSH服务于RK3399平台上的Ubuntu 18.04,实现远程连接
  • 深入探讨MySQL的二进制日志(binlog)选项
  • sparkml 多列共享labelEncoder - 详解
  • 一键解决MetaHuman播放动画时头部穿模问题
  • 忽然很好奇为什么素未谋面的大家都知道我是学姐?
  • UE网络编程完全指南:UDP TCP WebSocket实现详解
  • 配置Nginx服务器在Ubuntu平台上
  • 缓存一致性验证秘笈
  • 从十五岁的今天写给十六岁的明天
  • kali U盘启动持久化
  • 深入解析:Telerik UI for ASP.NET MVC 2025 Q3
  • Java依记 DAY02 - I
  • 元推理:汉字的发音,同音也是某种同构?
  • 题解:qoj7759 Permutation Counting 2
  • WAV 转 flac 格式
  • EtherCAT芯片没有倍福授权的风险
  • 为何是「对话式」智能体?因为人类本能丨对话式智能体专场,Convo AIRTE2025
  • 2014-2024高考真题考点分布详细分析(另附完整高考真题下载) - 详解
  • P4147 玉蟾宫(最大子矩形)
  • 2025 年 10 月西安房屋鉴定公司最新推荐排行榜:覆盖房屋安全评估、结构检测、承载力鉴定、危房鉴定领域,助您选专业机构