首页 > 其他分享 >计算机系统基础实验:缓冲区溢出攻击

计算机系统基础实验:缓冲区溢出攻击

时间:2023-04-21 21:11:33浏览次数:37  
标签:计算机系统 函数 clip msohtmlclip1 缓冲区 ASUJS Local 溢出 Users

实验目的

  1. 加深对IA-32函数调用规则和栈帧结构的理解

  2. 了解关于内存溢出攻击的原理,并通过 5 个 level 关卡的实验对堆栈有进一步理解

  3. 通过模拟缓冲区溢出攻击,了解如何去进行栈保护

  4. 了解程序的运行时操作以及了解这种形式的安全性弱点的性质,以便编写系统代码时可以避免这种情况

实验内容

  1. 对目标程序实施缓冲区溢出攻击(buffer overflow attacks)

  2. 通过造成缓冲区溢出来破坏目标程序的栈帧结构

  3. 继而执行一些原来程序中没有的行为

实验环境

  1. 32 位 Linux 操作系统

  2. 下载 buflab-handout 文件夹,并放入虚拟机

实践技能

Linux基本命令、IA32 汇编程序、gdb调试、objdump反汇编、gcc等。

实验要求

  1. Level 0 test 运行完后,不直接返回退出,而是跳到smoke函数处,继续运行,当 smoke 运行完毕后退出

  2. Level 1 在 Level 0 的基础上,使 getbuf 函数的返回指向 fizz 函数,同时将 fizz 函数的参数置为 userid 对应的 cookie 值

  3. Level 2 使 getbuf 调用后不执行 test 函数,而是执行 bang 函数,但是同时要修改global_value 的值为 cookie 值

  4. Level 3 使 getbuf 调用后,返回到 test 当中,但是不能破坏为 test 函数维护的堆栈状态,同时要让 test 函数调用 getbuf 后的返回值为自己的 cookie

  5. Level 4 要求和 Level 3 一致,但需要加上 –n 参数运行 bufbomb,此时会进入 testn 和 getbufn 函数而不是 test 和 getbuf 函数

实验过程

首先进入解压后的文件夹,在命令行输入“bufbomb -u <学号>”,其中“-u <学号>”是需要你提供的命令行参数,目标程序通过getcookie函数将学号转换成一个cookie(和使用makecookie完全一样的cookie),cookie将作为你程序的唯一标识,使你运行程序的栈帧地址与其他同学不一样。以下是我的userid和cookie:

![QQ截图20221125112035](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image002.gif)

由于汇编代码比较多,使用objdump -d命令将其反汇编到bufbomb.asm文件中查看。

![QQ截图20221125113409](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image004.gif)

Level 0

任务是让目标程序调用smoke函数。test函数调用了getbuf函数,getbuf函数的功能是从标准输入(stdin)读入一个字符串。以下是getbuf函数的汇编代码:

![QQ截图20221125114325](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image006.gif)

792行ebp-0x28的地址为Gets函数的参数,Gets函数将以该地址为起点向地址增大的方向保存字符,共0x28(40)个字节,即buf缓冲区为0x28(40)个字节,因此需要将 getbuf 函数的返回地址覆盖为smoke函数第一条语句的地址。以下为smoke函数的汇编代码:

![QQ截图20221125114943](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image008.gif)

361行为smoke函数的首地址0x08048bd2。

攻击字符串用来覆盖数组buf,进而溢出并覆盖ebp和ebp上面的返回地址,构造的攻击字符串的大小应为40+4+4=48个字节。攻击字符串的最后4字节应为smoke函数的首地址0x8048bd2,d2 8b 04 08(小端方式)。

![QQ截图20221202094640](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image010.gif)

为了方便可以把构造的字符串放在一个文本文件中,然后使用hex2raw工具将自己编写的攻击代码转化为字符串格式,最后执行bombbuf攻击目标程序。成功!

![QQ截图20221202093342](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image012.gif)

Level 1

任务是让目标程序使用特定参数调用fizz函数,以下为fizz函数汇编代码:

![QQ截图20221202094815](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image014.gif)

375行ebp+0x8传入函数的一个参数,376行将这个参数与0x804d140这个内存地址中的值比较,这个内存地址中保存着cookie的值,如果这两个值相等则成功。和第0关类似,首先用fizz函数的首地址覆盖getbuf的返回地址,使目标程序执行fizz函数,然后将fizz函数的返回地址覆盖掉,再用cookie覆盖返回地址上方的参数。这样就可以先跳转到fizz函数,然后在跳转后自己取到cookie作为参数。fizz函数的返回地址可以用任意4个字节的数覆盖,例如可以用00 00 00 00覆盖掉,其作用只是用来占位。

构造攻击字符串为:40(覆盖掉 buf)+4(覆盖掉 ebp 旧值)+4(用 fizz 函数地址0x8048bfa替换,冲掉返回地址)+4(占位置)+4(ebp+8位置为函数第一个参数,把 cookie 值按小端方式放到这里)。

![QQ截图20221202103346](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image016.gif)

我的cookie值为0x5216b8f0,按照上述步骤执行,成功!

![QQ截图20221202103330](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image018.gif)

Level 2

任务是让目标程序调用bang函数,并篡改全局变量。以下为bang函数的汇编代码:

![QQ截图20221202103700](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image020.gif)

因为全局变量存放的位置为.bss节或.data节,并不是存放在栈中的,前面的方法只能修改栈中的内容,无法修改全局变量的内容。所以我们需要换一种思路,先编写一段恶意代码,用其修改全局变量的值。

397行bang函数首地址为0x8048c49。401行将0x804d138内存地址中的内容移动到eax寄存器中,402行将0x804d140内存地址中的内容和eax寄存器中的内容进行比较。使用gdb调试,查看这两个内存地址中的内容:

![QQ截图20221202104606](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image022.gif)

0x804d138内存地址中的内容为全局变量,0x804d140内存地址中的内容为cookie值。

编写恶意代码,mov指令将cookie值赋给全局变量,push指令将bang函数的首地址压栈。

![QQ截图20221202112903](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image024.gif)

将恶意代码保存为.s汇编代码文件,然后用gcc –m32 –c生成.o可重定位目标文件,然后用objdump –d反汇编得到机器码。

![QQ截图20221202112936](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image026.gif)

在getbuf函数中,开辟的占空间为0x34(52)字节,而ebp-0x28只用了0x28(40)字节,因为buf 数组会被加载进入缓冲区,eax寄存器中放的就是buf数组首地址。

![QQ截图20221125114325](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image027.gif)

使用gdb调试,使用b命令在调用Gets函数处设置端点,查看eax寄存器中的内容,得到buf的首地址为0x55683228。

![QQ截图20221202111458](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image029.gif)

构造攻击字符串进行攻击,成功!

![QQ截图20221202113006](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image031.gif)

![QQ截图20221202112835](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image033.gif)

Level 3

任务是无感攻击,并传递有效返回值。前面的攻击都是使目标程序跳转到特定函数,进而利用exit函数结束目标程序运行,在这个过程中我们都把原来的恢复现场需要用的返回地址和原test的ebp给破坏了。boom这一关中,我们将修复这些被我们破坏的栈状态信息,让最后还是回到test中,让被攻击者不容易发现我们动了手脚,另外,构造攻击字符串,使得getbuf都能将正确的cookie值返回给test函数,而不是返回值1。设置返回值也就是更改eax(eax中保存的就是函数的返回值)的值,可以用mov指令设置eax存的为cookie值,更改完要进入test函数继续执行。以下为test函数的汇编代码:

![QQ截图20221202201626](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image035.gif)

需要将call getbuf函数的下一条指令的地址即492行的0x8048d64压入返回地址。编写恶意代码,先将返回值修改为cookie值,然后将call getbuf函数的下一条指令的地址压入返回地址,最后返回。

![QQ截图20221202112903](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image036.gif)

和第2关类似,将这些指令反汇编得到机器码。

![QQ截图20221202202519](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image038.gif)

恶意代码准备好以后,需要将返回地址更改为指向这个代码的位置,把恶意代码放到buf数组缓冲区内,返回地址和第2关一样。接下来要恢复ebp的值,需要得到ebp旧值。使用gdb调试,在getbuf函数第一行push ebp 的地址处设置断点。

![QQ截图20221202202614](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image040.gif)

然后使用x/p命令查看ebp的值,由图可知ebp的值为0x55683270,用原来的值覆盖被修改后的值,即无感攻击。

![QQ截图20221202202735](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image042.gif)

综上,构造攻击字符串进行攻击,成功!

![QQ截图20221202204538](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image044.gif)

![QQ截图20221202203123](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image046.gif)

Level 4

任务是栈帧地址变化时的有效攻击。这一关难度比前面都大,但也是承接上一关的,构造攻击字符串使getbufn函数,返回cookie值至testn函数,而不是返回值1,需要将cookie值设为函数返回值,复原被破坏的栈帧结构,并正确地返回到testn函数。但这一关与之前最大的不同在于地址空间随机化,每次攻击,被攻击函数的栈帧内存地址都不同,也就是函数的栈帧位置每次运行时都不一样,不能准确地跳转到栈空间的某个特定地址。因此,要想办法保证每次都能够正确复原原栈帧被破坏的状态,使程序每次都能够正确返回。

进入这一关需要加入-n选项,调用的函数是testn和getbufn,而不是前面的test和getbuf。这道题有5个test case,需要全部通过才算成功。

以下为testn的汇编代码:

![QQ截图20221202204942](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image048.gif)

虽然ebp是随机的,但是ebp和esp的相对位置是绝对的,根据527行可知ebp = esp + 0x14 + 4 = esp + 0x18。530行调用getbufn函数,返回后要从0x8048dd9这个地址开始执行,需要将这个地址压栈,并设置cookie给eax。

编写恶意代码:

![QQ截图20221202210401](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image050.gif)

将这些指令反汇编成机器码:

![QQ截图20221202210505](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image052.gif)

以下为getbufn函数汇编代码:

![QQ截图20221202205020](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image054.gif)

根据803行可知一共要填入0x208+4+4=0x210(528)字节。因为是随机跳转,所以把恶意代码放在最后,并把前面的全部空间都填上nop(0x90),使用nop进行滑行。nop不会执行任何操作,只有PC加一,机器码为0x90。不管程序跳转到哪个nop,最后都会执行到自己编写的恶意代码处。接下来需要寻找要跳转的地址,因为是随机化,所以buf首地址不确定。

使用用gdb调试,使用b命令在0x8049165地址处设置断点,查看eax的值。每执行一次,都要用c命令继续,然后执行下一次。重复五次,需要注意的是,需要在用r命令时使用-nu加uid。

![QQ截图20221202212706](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image056.gif)

根据调试的结果得到5个buf的起始地址:0x55683048、 0x55682ff8、0x55682fe8、0x55682fe8、0x55683038。取最大的地址0x0x55683048作为返回地址,这样就能滑行到恶意代码处,然后执行恶意代码。

综上编写恶意代码:

![QQ截图20221203173008](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image058.gif)

保存这段代码到.txt文件中,然后执行./hex2raw,注意需要添加-n选项,成功!

![QQ截图20221203172215](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image060.gif)

五个关卡的完整截图如下:

![QQ截图20221203174339](file:///C:/Users/ASUJS/AppData/Local/Temp/msohtmlclip1/01/clip_image062.gif)

完结撒花~~~

实验总结

通过这次实验,学习到了缓冲区溢出的原理和机制,加深了对函数调用规则的理解,也加深了对栈帧结构的理解。课本上大致描述了栈保护机制,通过模拟缓冲区溢出攻击,了解了栈保护机制,也加深了对课本理论知识的理解。把理论付诸实践,提高了自己的动手能力。通过对这些原理的学习,也提醒我以后在自己编写代码的过程中,要避免写出类似的危险代码,避免不必要的损失。同时,我还学习到了程序运行时操作,了解了这种形式的安全性弱点的性质,以后编写代码时也要多加小心。这次实验比上次实验要偏应用一些,第四关很难,所以做了很长时间,但是也学到了很多。

标签:计算机系统,函数,clip,msohtmlclip1,缓冲区,ASUJS,Local,溢出,Users
From: https://www.cnblogs.com/catting123/p/17341817.html

相关文章

  • IIS 内存溢出(32位程序运行)
    背景最近新接手了一个项目,服务器正常,用户量也没有变化,不定时出现内存溢出,重启iis或者回收线程就正常了review发现,因为业务原因缓存的东西并没有释放掉,但远远没有达到服务器内存上线,也没有受到预警邮件巴拉很久,发现32位系统存在内存上限为什么32位程序只能使用最大2GB内......
  • GPU-CPU命令行缓冲区
    目录书上25页命令行缓冲区是一个循环队列,且有大小限制(书上说是几千)CPU调用GPU干活,就会往队列屁股后添加指令GPU看到队列头有指令,就开始干活受CPU限制,受GPU限制受CPU限制:cpu繁忙,向命令行缓冲区写命令很慢,没有命令那gpu就闲下来了受GPU限制:gpu繁忙,命令行缓冲区已经写满......
  • ArcEngine|使用GP工具实现缓冲区分析与叠置分析
    ArcEngine|使用GP工具实现缓冲区分析与叠置分析GP工具简介地理处理是ArcGIS的一个重要概念,其目的是便于用户自动执行GIS的空间分析和建模任务。地理处理工具是将GIS中常用、可重复的操作,如提取与叠加数据、更改地图投影等封装成一个具有参数输人输出的交互式图形界面。地理处理......
  • Redis 报”OutOfDirectMemoryError“(堆外内存溢出)
    Redis报错“OutOfDirectMemoryError(堆外内存溢出)”问题如下:一、报错信息:使用Redis的业务接口,产生OutOfDirectMemoryError(堆外内存溢出),如图:格式化后的报错信息:{ "timestamp":"2023-04-1722:46:36", "status":500, "error":"InternalServerError&q......
  • 关于vite项目内存溢出无法正常打包的问题
    问题在vite+ts+vue3项目中时pnpmrunbuild构建项目导致无法正常打包解决思路排查问题时发现禁用router插件后能正常打包,禁用掉则会导致溢出。进一步发现是因为.vue文件过多的原因。考虑到可能是nodejs默认的内存不够,增大内存试试。增加到24GB后可以成功打包。项目继续开......
  • 计算机系统组成
    硬件主机CPU内存外设输入设备输出设备外存软件系统软件操作系统程序设计语言语言处理系统数据库管理系统实用程序(诊断、监控、病毒防护)应用软件......
  • Java_JVM的内存溢出异常
     JVM的内存溢出异常在Java虚拟机规范的描述中,除了PC(程序计数器)寄存器外,虚拟机内存的其他几个运行时区域都有发生OutOfMemoryError异常的可能。当发生OutOfMemoryError异常时,无法用try...catch捕捉。 在开始讲解之前,在这里先简单介绍下虚拟机启动相关的一些内存设置参数。因为Ou......
  • 《深入理解计算机系统第三版》第三章家庭作业参考答案
    简述最近看docker和k8s的底层实现原理,严重感觉自己对底层的知识了解不足,于是开始业余时间深入看一些底层书籍,就找了本据说是理解整个计算机体系的入门书-《深入理解计算机系统》.直接买的最新的第三版,从第三章开始看的,第二章接下来有心情再看(看了几眼全是如何手算进制间计算之类......
  • Redis缓冲区溢出及解决方案
    缓冲区(buffer),是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。一、Redis缓冲区溢出影响在Redis中,主要有三个场景用到了缓冲区的概念。在客户端和服务器端之间进行通信时,用来暂存客户端发......
  • Redis缓冲区溢出及解决方案
    缓冲区(buffer),是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。一、Redis缓冲区溢出影响在Redis中,主要有三个场景用到了缓冲区的概念。在客户端和服务器端之间进行通信时,用来暂存客户端发......