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

20253921 2025-2026-2 《网络攻防实践》第九周作业

20253921 2025-2026-2 《网络攻防实践》第九周作业

1.实践内容

(1)手工修改可执行文件执行流程:通过IDA分析程序中的mainfoogetShell函数,理解程序原本的调用关系,并通过修改汇编指令,将main中原本调用foo的流程改为直接调用getShell,从而获得Shell。

(2)利用缓冲区溢出覆盖返回地址:分析foo函数中gets函数造成的栈缓冲区溢出漏洞,构造特定长度的攻击输入,覆盖函数返回地址,使程序返回时跳转到getShell函数,实现对程序执行流程的劫持。

(3)注入并执行自制shellcode:在关闭地址随机化后,使用gdb定位栈中缓冲区地址,构造包含填充数据、返回地址、NOP滑行区和shellcode的payload,使程序跳转到栈中执行自制shellcode,从而获得Shell。

2.实验过程

2.1 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数

使用IDA打开实验程序20253921_wangbo_pwn,在左侧函数窗口中可以看到程序包含mainfoogetShell等函数。其中main是程序入口逻辑函数,foo用于接收并回显用户输入,而getShell是程序中隐藏的函数,正常情况下不会被执行。

随后双击查看getShell函数,并切换到伪代码窗口。可以看到getShell函数的核心代码为:return system("/bin/sh");

这说明如果程序能够执行到getShell函数,就会调用system("/bin/sh"),从而启动一个Shell。因此,本步骤的关键就是修改程序执行流程,让main函数中原本调用foo的位置改为调用getShell

接着回到main函数进行分析,可以看到main函数中存在对foo函数的调用指令,即程序正常情况下会执行call foo。为了改变程序执行流程,选中该调用指令,然后使用IDA的汇编修改功能,将原来的调用目标foo修改为getShell。在IDA中对该指令进行修改时,将指令内容改为:call getShell

为了将修改结果保存到原始可执行文件中,在IDA菜单栏中依次选择EditPatch programApply patches to input file,将修改后的补丁应用到输入文件。保存完成后,桌面上的20253921_wangbo_pwn文件即为已经修改过执行流程的程序。

最后回到Kali终端,在桌面目录下直接运行程序时,系统提示权限不足,说明当前文件没有执行权限。于是使用如下命令为程序添加执行权限:chmod +x 20253921_wangbo_pwn。添加权限后再次运行程序:./20253921_wangbo_pwn。程序执行后进入Shell环境。随后输入验证命令:whoami。终端输出当前用户为kali,说明程序已经成功执行getShell函数,并获得了可用Shell。

通过IDA手工修改程序中的函数调用指令,将main函数中原本的call foo修改为call getShell,再将补丁写回可执行文件,最终成功改变程序执行流程,实现了直接调用getShell函数并获得Shell的目标。

2.2 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数

先在IDA中查看foo函数的反汇编代码。可以看到foo函数中定义了局部变量s,其位置为byte ptr -1Ch,说明该缓冲区位于栈中。同时,函数中调用了gets函数读取用户输入,再调用puts函数输出输入内容。由于gets函数不会检查输入长度,如果输入内容超过缓冲区大小,就会造成栈缓冲区溢出,从而覆盖函数保存的返回地址。

根据IDA中的栈变量信息,局部变量s距离返回地址需要填充一定长度的数据。结合实验分析,构造攻击字符串时先输入32个字符用于填充缓冲区和覆盖栈上的中间数据,然后再追加getShell函数地址,使程序返回时跳转到getShell函数。在Kali终端中进入桌面目录后,使用Python生成攻击载荷文件payload,命令如下:python3 -c 'import sys,struct; sys.stdout.buffer.write(b"A"*32 + struct.pack("<I", 0x0804847d))' > payload

其中,b"A"*32用于填充缓冲区,struct.pack("<I", 0x0804847d)用于按照小端序写入getShell函数地址0x0804847d。由于程序运行在x86小端环境下,因此地址需要按小端格式写入。

随后使用管道将构造好的payload作为程序输入,执行命令如下:(cat payload; cat) | ./20253921_wangbo_pwn。程序运行后,前面的填充字符被foo函数读取,随后溢出的数据覆盖了函数返回地址。当foo函数执行结束返回时,程序没有回到原本的调用位置,而是跳转到了getShell函数。由于getShell函数内部执行system("/bin/sh"),因此程序成功启动Shell。为了验证是否成功获得Shell,在终端中输入命令:whoami。程序返回结果为:kali。说明当前已经成功进入Shell环境,缓冲区溢出攻击生效。

通过分析foo函数中的gets危险函数和栈变量位置,构造32字节填充数据加上getShell函数地址0x0804847d的攻击输入,成功覆盖返回地址并触发getShell函数,实现了利用Bof漏洞获得Shell的目标。

2.3 注入一个自己制作的shellcode并运行这段shellcode

为了降低实验过程中的地址随机化影响,在Kali终端中关闭地址空间随机化,执行命令如下:echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

命令执行后返回0,说明地址空间随机化已经关闭。随后进入Desktop目录,直接运行20253921_pwn程序,注意不能用原来修改过的程序,需要重新传输原本的文件。程序正常等待用户输入,说明实验程序可以正常执行,不要关闭这个终端,保持待输入,再打开新的一个终端进行实验。

接着由于需要调试程序运行时的栈地址,先安装并使用gdb调试工具。

安装完成后,通过ps -aux | grep "20253921_pwn"查看程序进程号,这里我的程序进程号是23709,是重启过前面的20253921_pwn程序,然后使用gdb attach附加到正在运行的20253921_pwn进程上进行调试。进入gdb后,先设置反汇编格式为Intel风格,并查看函数调用栈,执行命令如下:set disassembly-flavor intel,bt

从调用栈中可以看到程序当前位于foo函数中,并且调用链中包含gets函数、foo函数和main函数,说明程序正在等待foo函数中的输入。随后切换到foo函数对应的栈帧,并查看缓冲区地址,这里我的foo函数是8,所以命令如下:frame 8p/x $ebp-0x1c。输出结果显示缓冲区地址为0xffffcf5c。该地址是后续构造payload时需要使用的关键地址,用于让返回地址跳转到栈中放置shellcode的位置。

随后编写exploit.py脚本,用于生成包含shellcode的攻击输入。脚本中首先接收命令行传入的缓冲区地址,然后设置shellcode内容。该shellcode的作用是执行/bin/sh,从而获得Shell。脚本中设置offset = 32,表示先填充32个字节覆盖到返回地址位置;然后将返回地址设置为buf_addr + offset + 4,使程序返回时跳转到后面NOP滑行区和shellcode所在位置。

脚本构造payload的主要思路为:先使用A填充缓冲区,再写入新的返回地址,接着写入一段NOP指令,最后追加shellcode。这样当程序返回地址被覆盖后,就会跳转到栈中的NOP区域,并继续滑向shellcode执行。把生成的文件传输至kali中,之后在终端中根据前面gdb得到的缓冲区地址生成payload文件,执行命令如下:python3 exploit.py 0xffffcf5c > payload。最后使用管道将payload输入到目标程序中,执行命令如下:(cat payload; cat) | ./20253921_pwn。随后输入验证命令:id

终端输出当前用户信息,例如uid=1000(kali)gid=1000(kali)等内容,说明shellcode已经成功执行,并获得了可交互的Shell环境。这里先是关闭地址随机化、使用gdb定位栈中缓冲区地址、编写exploit.py构造包含NOP滑行区和shellcode的payload,最终成功利用foo函数的缓冲区溢出漏洞执行自制shellcode,实现了注入并运行shellcode的目标。

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

  • 问题1:刚开始实验的时候使用的是在Windows 2000里面自带的IDA,在这个软件中无法轻松完成反编译,比较麻烦。
  • 问题1解决方案:在网上自己下载最新的IDA,安装至宿主机,完成对文件的反编译,再将修改后的文件传输至kali中。

  • 问题2:在使用gdb时下载出现问题报错了,显示我的 Kali 软件包索引过期了。且最开始attach找不到相应的函数。

  • 问题2解决方案:执行sudo apt update,sudo apt install gdb,成功解决,后将前面终端开启的文件重启一遍,得到新的id,再重新attach,最终得到相应的函数。

4.学习感悟、思考

通过本次实验,我对缓冲区溢出攻击的基本原理有了更直观的理解。以前只是从概念上知道程序可以通过覆盖返回地址改变执行流程,这次通过IDA分析函数、修改调用指令和构造payload,真正看到了程序执行流程是如何被控制的。

在实验过程中,我也体会到工具使用和细节判断很重要,例如地址的小端序表示、栈地址定位、关闭地址随机化以及payload长度都会影响实验结果。通过不断调试和验证,我认识到漏洞利用并不是简单执行命令,而是需要结合程序结构、内存布局和调试结果进行分析。

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

相关文章:

  • 如何让扫描PDF开口说话:离线环境下OCRmyPDF的3大实战技巧
  • 构建AI智能体信任基础设施:从技能验证到支付结算的完整方案
  • 从0到1实现Balatro游戏后端(4):玩家手牌操作(出牌 / 弃牌 / 补牌)与状态流转设计
  • 终极微信聊天记录导出指南:三步永久保存你的珍贵对话
  • Flutter+Supabase构建AI学习平台:3天完成54家服务商整合
  • 游标分页(Cursor-based Pagination)
  • Lattice LFCPNX-100 HSB+Fpga开发详解: 2.1 MAC+PCS以太网SFP光口传输
  • PlantUML编辑器:用文本快速绘制专业UML图的终极指南
  • 构建极简研究档案库:基于本地文件系统的学术知识聚合与检索方案
  • 基于MCP协议构建智能求职助手:从架构设计到工程实践
  • 不用专业知识 OpenClaw 普通人也能轻松部署
  • 告别手动拷贝!Qt Creator远程调试嵌入式Linux应用的保姆级配置流程(基于Qt 5.15+)
  • GitHub中文界面终极指南:3分钟告别英文困扰
  • 向量数据库与RAG管道:从核心组件到系统工程的关键认知
  • 如何快速掌握OBS多平台直播:obs-multi-rtmp插件完整教程
  • Linux入门到实战·学习笔记系列——10.计算机网络基础概论
  • 5Why分析方法和鱼骨图分析方法
  • 【Claude Code的Harness Engineering实现】:12-状态持久化与Checkpoint(State Persistence)
  • 【测试】之自动化测试概念篇
  • 2026年企业营销必知:揭秘GEO——比SEO更重要的下一代流量密码
  • UniversalUnityDemosaics:终极Unity游戏视觉恢复工具完整指南
  • 读工业软件简史01工厂设计
  • 猫抓插件终极教程:三步轻松下载网页视频资源
  • 【大模型篇】谈谈A2A协议(Agent-to-Agent)
  • 5分钟快速上手:微软官方XML编辑器XML Notepad完全指南
  • 别再只会显示数字了!用TM1637四位数码管做个简易时钟/计数器(附Arduino和STM32代码)
  • 基于保形预测的校准检索:为智能体系统注入统计可靠性
  • AI Agent项目失败率高达80%?深度解析Agent避坑指南
  • 3分钟快速上手:GitHub中文化插件终极指南,让GitHub界面说中文
  • 基于广义加性模型的气候模型偶然不确定性量化实践