rop [ 一] 栈溢出和简单ROP思路

本文介绍了返回导向编程(ROP)的概念,它是栈溢出漏洞利用的一种方式。在栈不可执行策略启用后,通过修改ret指令,利用程序内部的代码片段(gadget)来控制程序执行流程。文章详细阐述了栈帧结构、程序运行流程、漏洞原理,以及如何利用ROP修改ret、传递参数、调用函数,包括32位和64位环境下的差异,并提及shellcode的写入方法。
摘要由CSDN通过智能技术生成

ROP

ROP即返回导向的编程

主要是用在栈溢出
在栈堆不可执行开启后,栈溢出不能简单的向栈中写入shellcode利用jmp rsp运行,因此开发出的一种栈溢出利用手段,主要的意思就是修改ret的位置,运行到一些程序内部的代码片段(gadget)的位置,然后通过这些去控制程序的栈空间,来控制:寄存器,参数传递,函数调用,
由于gadget的使用要是最后ret结尾,由此成为面向ret的编程。

这一篇是结合经典文档:《蒸米的一步步学ROP》自己的笔记

排布首先是栈溢出的简述,然后就是按照攻击的思路去划分出的知识框架。

栈溢出

首先还是先介绍有名的栈溢出漏洞,

首先是程序接受的输入数据,一般是保存到栈中,而程序运行时调控变量参量和函数调用的主要工具就是栈,(eax一直用于返回值传递,在64位中寄存器会参数参与参数传递),

栈中的栈帧结构保证函数的调用,

栈帧:

栈内的一块区域,是函数调用时形成的,作用就是保存和该函数有关的参数变量返回地址等,且一个函数能够控制的栈内空间也只有自己的栈帧, 这样也就实现了函数之间的隔离

也辅助程序的流程控制,

程序运行流程

首先程序运行时是永远在运行rip/eip寄存器指向的指令,而我们的程序运行的底层汇编语言永远不会直接改变这个寄存器,而是通过jmp,call,ret,各种条件的jmp,来间接的影响rip/eip寄存器,而影响程序的运行,

jmp和条件的jmp类:

都可以其后直接跟一个地址,直接跳转到该位置运行(其实相当于直接给rip/eip赋值了)

call:

函数调用指令,调用其实相当与jmp,但还需要顾及调用函数需要返回,这里就用到了栈保存这个返回地址,
相当与push rip+xx; jmp xxx,这里就是将原本该call下一个语句的rip保存到栈,然后跳转到目标位置,

ret:
函数执行完毕后的返回指令,从栈中取出call指令保存的返回地址,然后跳转过去执行,

相当与pop jmp,或者就pop rip/eip

漏洞

而将用户输入的信息传入栈中是一个比较危险的事情,

因为我们的返回地址同样保存在栈中,当程序读入的值超过了该函数的栈帧空间的大小,就有可能导致输入的数值覆盖掉保存的返回地址,也就是可以构造一个输入,随意的修改返回地址,修改ret指令执行后rip/eip的值,从而控制程序流程,

利用

栈溢出的利用主要就是修改ret控制程序流程,从而让我们的程序执行我们想让其执行的代码。

这就牵扯到一个问题 q1: 将ret改成啥?

将ret修改调用函数时又会出现另一个问题 q2:修改了以后我们调用函数时需要传入的参数怎么改?

最后假如我们的程序和导入的库中不能够得到我们想要的函数呢,q3:如何写一个shellcode并使其执行。

修改ret

后门函数

一般很简单的pwn会出现这种类型,就是一个比较典型的后门函数,直接计算距离然后就可以修改ret运行到对应的函数直接getshell或者catflag的:

payload = 'a' * xxx + p64(ret_addr)/p32(ret_addr)

ELF中查找函数

我们首先说到pwntools的ELF函数,导入一个elf文件,并允许从其中查找相应的地址。

常用来导入我们的程序和该程序用到的libc.so文件

这个就需要一定的理解了,想要理解需要一些关于动态链接和重定向的知识。

elf = ELF('levelxx')
libc = ELF('libc.so'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值