缓冲区溢出攻击实训

缓冲区溢出攻击实训

实验网址:https://seedsecuritylabs.org/Labs_16.04/Software/Buffer_Overflow/

(实验所用源码对应:exploit.c 、 stack.c)

实验楼:https://www.shiyanlou.com/courses/231

IA32体系下的栈帧结构

缓冲区溢出攻击实训_第1张图片
在32位CPU体系架构下的某进程中的用户空间函数调用栈结构如上图所示。

优质的IA32体系C语言函数调用栈博客:https://www.cnblogs.com/clover-toeic/p/3755401.html

在进程中,每发生一次函数调用都会开启一段栈帧(stack frame),栈帧的边界由EBP寄存器和ESP寄存器指明。其中EBP寄存器保存栈帧基地址,ESP寄存器保存栈帧顶地址。在不考虑栈中保存上一次调用的现场时(只考虑函数的内容准备),一般EBP寄存器后会先放入本地局部变量、下一个函数调用传递的参数以及调用结束后继续执行指令的地址。

因此,实际上被调用的函数需要用到传递的参数时,都会以EBP保存的栈帧基地址为基础向上(高地址)寻址拿到传递的参数。

因为ESP寄存器随着栈帧的入栈出栈会变化,因此一般寻址时(例如拿传递的参数)会用EBP寄存器,这也是每一个栈帧基地址都会存储上一个栈帧的基地址(压栈保存上一个栈帧的EBP)而不是栈帧顶部地址(ESP)的原因。

浅析栈溢出攻击原理

函数内的局部变量内容都是存储在栈帧中,因此可以通过构造对局部变量的输入,将数据溢出到预期位置,达到攻击效果。

根据上面的栈帧结构图,我们可以看到在32位CPU体系架构下,每发生一个函数调用会创建的一个栈帧,一旦在该被调用的函数内通过构造输入数据溢出该栈帧后,首先遇到的就是上一个栈帧(也就是调用此函数的"父函数")调用结束后的返回地址。

缓冲区溢出攻击实训_第2张图片

利用这一原理,我们可以把精心构造的shellcode地址写到返回地址,函数返回后按照正规流程CPU会将这一地址的内容出栈赋值给EIP寄存器,这样就可以跳转到shellcode的地址进行指令执行,达到攻击效果。

实验步骤

该实验环境为SeedsLab-ubuntu32位系统。

老师已经提供好”获得攻击输入内容“的C语言源码exploit.c。调用这一函数后会将构造好的输入写入到‘badfile’文件中,然后直接将文件内容直接读出输入到有缓冲区溢出漏洞的输入位置即可完成攻击。

exploit.c构造参数的获得

要想获得有效攻击的输入内容,我们需要对有缓冲区溢出漏洞的stack.c文件进行分析。

1、使用gdb分析缓冲区和返回地址的相对距离(可以准确找到返回地址的位置,写入shellcode地址)

gdb -q stack_gdb
b fob
run
p $ebp

NKlRgS.png

根据上面的栈帧图结构我们可以知道,上一个栈帧中存储函数的返回地址的位置就在当前栈帧的栈帧基地址+4的位置,也就是当前
EBP寄存器+4。

NK1mVA.png

经过计算上一栈帧的返回地址如上。

&上一栈帧返回地址 - &buffer 就可以得到缓冲区要想准确覆盖返回地址需要构造的数据长度大小。(&取地址符,表示内存地址)

NK1WPx.png

NK1jRf.png

得到缓冲区长度为24时,再写入内容就会覆盖到返回地址中。

2、构造shellcode,将shellcode的地址构造到返回地址的位置。

在exploit.c中,shellcode被写到了buffer+100的位置。

前面我们知道&buffer = 0xbfffeab4。则&shellcode = 0xbfffeab4 + 0x64 = 0xbfffeb18

buffer[24] = “0x18”

buffer[25] = “0xeb”

buffer[26] = “0xff”

buffer[27] = “0xbf”

提升权限

sudo chmod u+ssudo chown root stack,shellcode中setuid(0)。

执行程序

NKdOBV.png

成功拿到rootshell。

栈帧结构图解

缓冲区溢出攻击实训_第3张图片

左图正常栈帧,右图是此实验攻击后的栈帧情况。

你可能感兴趣的:(课程笔记——软件系统安全)