BuringStraw

BuringStraw

ROP返回导向编程

看从零到一第一遍有没懂的地方记录一下

长篇大论:#

现代操作系统往往有比较完善的 MPU 机制,可以按照内存页的粒度设置进程的内存使用权限。内存权限分别有可读(R)、可写(W)和可执行(X)。一旦 CPU 执行了没有可执行权限的内存上的代码,操作系统会立即终止程序。

在默认情况下,基于漏洞缓解的规则,程序中不会存在同时具有可写和可执行权限的内存,所以无法通过修改程序的代码段或者数据段来执行任意代码。针对这种漏洞缓解机制,有一种通过返回到程序中特定的指令序列从而控制程序执行流程的攻击技术,被称为返回导向式编程(Return-Oriented Programming,ROP)。

利用以 ret(0xc3)指令结尾的指令片段(gadget)构建一条 ROP 链,来实现任意指令执行,最终实现任意代码执行。具体步骤为:寻找程序可执行的内存段中所有的 ret 指令,然后查看在 ret 前的字节是否包含有效指令;如果有,则标记片段为一个可用的片段,找到一系列这样的以 ret 结束的指令后,则将这些指令的地址按顺序放在栈上;这样,每次在执行完相应的指令后,其结尾的 ret 指令会将程序控制流传递给栈顶的新的 Gadget 继续执行。栈上的这段连续的 Gadget 就构成了一条 ROP 链,从而实现任意指令执行。

过程:#

例程:https://buuoj.cn/challenges#[第六章 CTF 之 PWN 章] ROP

ROPgadget --binary rop得到所有 gadget

太少了,所以要搞到 libc 的加载地址,然后在里面找 syscall

用这个 payload 可以获得 puts 的地址(pop_rdi 是 pop rdi 的 gadget)。

具体原理:

返回地址在 0x12 个字节后面,

执行到leavepop_rdi在栈顶(上面的被清理了)

执行到ret时,会跳到pop_rdi所在的地址,并把栈顶的pop_rdi弹出去,所以之后栈顶是puts_got

puts_got是指向puts真实地址的指针

然后执行pop_rdi,将puts_got放进rdi

ret 到puts,根据调用约定(参考程序已有的 puts 调用),rdiputs的参数,所以地址就被输出了。

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。