栈溢出漏洞学习与剖析

0x00

刚开始接触pwn,但是pwn呢!不应该只会做题,应该理解里面的原理,所以我们来看看程序里面究竟蕴含着什么神秘!

0x01

程序的执行就是一种线性的"纸",上面有许多内容。在这里插入图片描述
就是一张"纸",在上面写了很多内容,Stack是栈,Heap是堆,这两个是最为关键的,因为接下来我们利用的就是有关这两个的漏洞。
程序在上面执行,code代码段(其实就是汇编指令)利用这里面的指令一步一步的运行。你可能有疑问?while和if和for等其实就是jmp等跳转指令,从一张"纸"的第一行开始"写",到了第三行(假设)有个jmp语句,那就跳转到它所指向的语句。
对于栈,那么存在两个最为关键的寄存器,如下:

ESP(Extended Stack Pointer)为扩展栈指针寄存器,是指针寄存器的一种,用于存放函数栈顶指针。与之对应的是EBP(Extended Base Pointer),扩展基址指针寄存器,也被称为帧指针寄存器,用于存放函数栈底指针。
ESP为栈指针,用于指向栈的栈顶(下一个压入栈的活动记录的顶部),而EBP为帧指针,指向当前活动记录的底部。

就是栈的两端。


还有程序中运行的时候进入一个函数里面就会开启一个新的栈帧,
mov ebp,esp;就是将旧栈帧中的帧基指针赋给新的栈底部位置。然后就是sub esp,0xxx;开辟该函数的局部变量空间。mov esp,ebp;pop ebp; (相当于leave指令) 函数结束,该函数栈消失。

0x02

栈溢出 属于缓冲区溢出,指的是程序向栈中某个变量中写入的字节数超过了这个变量本身所申请的字节数,因而导致与其相邻的栈中的变量的值被改变。
补充一下,栈顶应该属于理想中的底部,栈低应该属于理想中的顶部。
一个小的知识点
系统栈 又叫调用栈。调用栈最经常被用于存放子程序的返回地址。在调用任何子程序时,主程序都必须暂存子程序运行完毕后应该返回到的地址。因此,如果被调用的子程序还要调用其他的子程序,其自身的返回地址就必须存入调用栈,在其自身运行完毕后再行取回。在递归程序中,每一层次递归都必须在调用栈上增加一条地址,因此如果程序出现无限递归(或仅仅是过多的递归层次),调用栈就会产生栈溢出。

在这里插入图片描述
这里再上张图。

0x03

基本ROP来看。
ROP 的全称为Return-oriented programming(返回导向编程),这是一种高级的内存攻击技术可以用来绕过现代操作系统的各种通用防御(比如内存不可执行和代码签名等)。
BSS段 通常是指用来存放程序中未初始化的或者初始化为0的全局变量和静态变量的一块内存区域。特点是可读写的,在程序执行之前BSS段会自动清0。既然可读写那么只要能够在栈内写入的payload,然后再转移到此处,并且执行权限就可以控制。通过strncpy函数达到这一目的。

其实ROP和上面的栈溢出一样,就是修改了eip的地址,是它可以返回到我们想要它返回的函数。

0x04

但是针对二进制漏洞不能光说不练,我们可以找到一些例题来详细的讲解一下!
首先我们对于栈溢出最为常用的攻击手法便是ROP了,那么,ROP又细分为什么呢?
ret2text,ret2libc,ret2shellcode,ret2dl_resolve等!当然还有BROP,SROP等,不过此时我们仅仅讨论相对简单一些的类型!
其中最为关键的便是ret2libc,ret2libc是什么呢?
在这里插入图片描述
libc地址是随机的,即我们必须得到其真实地址即可利用。
关于例题的讲解便不再于本篇讨论,下方给出链接:

ROP点我直达
位于链接中例题jarvisoj_level4即为ret2libc,
例题jarvisoj_level3_x64为ret2csu(也是ROP类型的一种形式,攻击手法更高明的还有ret2csu_fini),
例题pwnable_orw为ret2shellcode


ret2dl_resolve点我直达
该利用难度较大,但是我们依旧可以完成利用

posted @ 2021-03-13 09:15  望权栈  阅读(17)  评论(0编辑  收藏  举报  来源