Skip to content

Latest commit

 

History

History
166 lines (137 loc) · 8.89 KB

Drive_to_the_target.md

File metadata and controls

166 lines (137 loc) · 8.89 KB

Drive to the target

Category: Coding

Description

Excellent work! With your fine sleuthing skills, you managed to find a picture of the handsome creature with its pet biped. At last friends and companionship may be near!

Like all inhabitants of this world, you spend an inordinate amount of time on the site, stalking and comparing your life to that of others. The first thought that springs to your mind is "Why haven't I ever been to Mauritius on holiday?" followed swiftly by "What is a Mauritius anyway?" But after a while and with language successfully deciphered, you've made contact with the lifeform in the picture, you have a "date"? You're given the address of where to meet your potential interest. "1 Banana way, beware of the glass." An odd address, especially that last part. So how do you get there? You land your ship and begin to search.

https://drivetothetarget.web.ctfcompetition.com/

Solution

We visit the attached website and see the following form:

<body>
     <p>Hurry up, don't be late for you rendez-vous!
      <form method="get" action="/">
        <fieldset>
        <legend>Pick your direction</legend>
         <input type="number" name="lat" value="51.6498" min="-90" max="90" step="0.0001">
         <input type="number" name="lon" value="0.0982" min="-180" max="180" step="0.0001">
         <input style="display: none" name="token" value="gAAAAABdIIdwScIB_NAfiCCjS-DQroCC-_M2uKbNlUMWE4SZdy3SNpNVuCbCp5QS4bZUhhY57ncdHSa8lVX1d85q3DCBW5SkZutF0_xG-2Jpnv0T3vBl5BeAJ85DqgDuX9VMmZTw2BUJ">
         <button type="submit">go</button>
        </fieldset>
      </form>
      <p></p>
   </body>

We can modify the latitude or longitude and submit the form. The response will tell us if we're moving closer, further or too fast (which means we must either wait between submissions or choose a closer coordinate).

The concept is pretty simple. We'll write a short script to drive us to the target. The script will choose the correct direction by attempting different directions until it receives an indication that it is getting closer. Diagonal movement will be prioritized at first as an optimization. It will continue moving in the same direction until there is an indication that the chosen direction isn't optimal anymore. Then it will choose another direction, without allowing diagonal movement (since allowing it might cause an infinite loop of moving further and back closer again).

The code:

from collections import namedtuple
from bs4 import BeautifulSoup
from enum import Enum
import requests
import random
import pickle
import time
import os

CACHE_FILE = "cache.db"
URL = "https://drivetothetarget.web.ctfcompetition.com/"
Result = namedtuple('Result', 'lat lon token msg')

UNIT = 0.0001

class Message(Enum):
    CLOSER      = 1
    FURTHER     = 2
    TOO_FAST    = 3
    OTHER       = 4

def extract_info(html):
    parsed_html = BeautifulSoup(html, features="html.parser")
    lat = parsed_html.body.find("input", attrs={"name": "lat"})["value"]
    lon = parsed_html.body.find("input", attrs={"name": "lon"})["value"]
    token = parsed_html.body.find("input", attrs={"name": "token"})["value"]
    paragraphs = parsed_html.body.find_all("p")
    msg_type = Message.OTHER
    if len(paragraphs) > 1:
        msg = paragraphs[1].text
        if "closer" in msg:
            msg_type = Message.CLOSER
        elif "away" in msg:
            msg_type = Message.FURTHER
        elif "fast" in msg:
            msg_type = Message.TOO_FAST
        else:
            print (msg)

    return Result(lat, lon, token, msg_type)

def send_info(s, lat, lon, token):
    r = s.get(URL, params = {"lat": str(lat), "lon": str(lon), "token": token})
    return extract_info(r.text)

def get_direction(s, res, timeout, allow_diagonal = False):
    print ("Changing direction . . .")
    
    directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
    random.shuffle(directions)

    if allow_diagonal:
        directions = [(-1, -1), (1, 1), (1, -1), (-1, 1)] + directions
    for direction in directions:
        while True:
            time.sleep(timeout)
            res = send_info(s, float(res.lat) + (UNIT * direction[0]), float(res.lon) + (UNIT * direction[1]), res.token)
            if res.msg == Message.CLOSER:
                print ("New direction: {}".format(direction))
                return res, direction
            elif res.msg == Message.TOO_FAST:
                timeout += 1
            else:
                break
    return (None, None)


s = requests.session()

if os.path.exists(CACHE_FILE):
    res = pickle.load( open( CACHE_FILE, "rb" ) )
else:
    r = s.get(URL)
    res = extract_info(r.text)
    
try:
    timeout = 0.8
    res, direction = get_direction(s, res, timeout, True)

    print ("Starting to drive . . .")

    while res is not None:
        time.sleep(timeout)

        res = send_info(s, float(res.lat) + (UNIT * direction[0]), float(res.lon) + (UNIT * direction[1]), res.token)
        print (res)
        if (res.msg == Message.FURTHER):
            res, direction = get_direction(s, res, timeout, False)
        elif (res.msg == Message.TOO_FAST):
            timeout += 0.1
        elif (res.msg == Message.OTHER):
            break

except Exception as e:
    print (e)
finally:
    pickle.dump( res, open( CACHE_FILE, "wb" ) )

It takes a while. The last few lines of are:

Result(lat='51.49139999999475', lon='-0.19269999999999685', token='gAAAAABdIK-KlQ8jp2wP7JenziknWUFTk5L1TGDqJKitMflAkgYYef0bYHFtyv0o9Nn4wYY7xlDBUK4e-7TVgM4dzYpfht-1PMEVwYKypsP3s8QQva9_IOb0-rvSnTwWkP7aQpauRT92', msg=<Message.CLOSER: 1>)
Result(lat='51.49149999999475', lon='-0.19269999999999685', token='gAAAAABdIK-LHp-83iXQSjE9CFGqlBohYTBJOttg9F980QurnlVDPT_mx-kAr0V4B9wd88fwlyCYCFIxWp9YEGy_9GTS-GUI7QzdWa3mq9fbHXuU4n5onhcmibV7Fc_ui5iRy_ZlP_1z', msg=<Message.CLOSER: 1>)
Result(lat='51.491599999994754', lon='-0.19269999999999685', token='gAAAAABdIK-Ml1x5vdTkghk85clT6JAd6mm_N4OBVjdr3cQEoCRmIJct17MDD9s3qdlq-mMcJ9F2QesR_x2ViCBTcpVY_KyUJOeSiyO7idNbK_XIQEpTa3pi0kmTq3j4qqzwIBFGBUu9', msg=<Message.CLOSER: 1>)
Result(lat='51.49169999999476', lon='-0.19269999999999685', token='gAAAAABdIK-O_fpi5-K-DI7b55eXsk_6A89M4AuKI9h1HKHmMM4aKgcIVSoYGzmlxe9XyQAA2zOpjhmRzC2brNDIpwaFhufvNLk-bQBASTSHAjCVVVWlisZtUSCkQGrk4_QYIP8SUp_o', msg=<Message.CLOSER: 1>)
Result(lat='51.49179999999476', lon='-0.19269999999999685', token='gAAAAABdIK-Pw1VE2QfgV80gT7YWaNGyw64bWrB0HKWMsfRq8K9sol-8QrXuhafBqjOYGNCvlzNe_EC5465hE6fS3CAB2lYrbMpu_crFLg0ZUaFrkj9Zu6fA3y9tEVPnTjOdWoH010vx', msg=<Message.CLOSER: 1>)
Result(lat='51.491899999994764', lon='-0.19269999999999685', token='gAAAAABdIK-QCjUu42odLrAsnTWKfZ3RHiP2AmHjdh4mWY3mi7-aVcCi8T9GbbD4Nb56zNMI1XTStmjdC2GRUKRmuVNvtmp1rGoL0CxDRsIXR_BnhqynddHwBcv69t5ROunp1zwrs_1i', msg=<Message.CLOSER: 1>)
Result(lat='51.49199999999477', lon='-0.19269999999999685', token='gAAAAABdIK-RsI4wVFyRFwdphXzAgLmBrwXP8IN3Yrmvi9TwmfObe3XpctxVaAT6kVpCoIdYzVfUDkKYZAVMB67f48_oqseE4dRVFUkdwI5F9BfbHiawcMEf7b59D0uU7NyDttemy9Wl', msg=<Message.CLOSER: 1>)
Result(lat='51.49209999999477', lon='-0.19269999999999685', token='gAAAAABdIK-SWKxdb2j3_kmpN6g0xeEYfUgXg1_JhWoNpWSaPvsvJdQ_n3XCAl4MrcztCpMYupYZ63SAKc_ku9-5mW4PxNKK35W-c6dyhY_BUMLpWA4RWbrcrmFpYJV7W_xMpmqvhEBU', msg=<Message.CLOSER: 1>)
Result(lat='51.492199999994774', lon='-0.19269999999999685', token='gAAAAABdIK-TMe7cFgRviWQ102nugUb3uqWVTBff061dAxax1iKT0dUyKlKm3gVGvFzmcdZWwistCGlr-gcegz3eWCdLHKx1HQBErmPTfzK6ApY_2PvdTYIdPPrtP140Pdu5cxQveB2b', msg=<Message.FURTHER: 2>)
Changing direction . . .
New direction: (-1, 0)
Result(lat='51.49199999999477', lon='-0.19269999999999685', token='gAAAAABdIK-VYUb5Yl29ogPMRODBQzJqLZ5mK2oFBqWeJK2-12KYMTkxSGLU1XqekklK4Ejftfmq9DI3B_BUOKKhTWMFCExwITrwI_eDygbohn2EJ2NhSK5ptJc7w8-pXD_IFTBzPz2X', msg=<Message.FURTHER: 2>)
Changing direction . . .
New direction: (0, -1)
Result(lat='51.49199999999477', lon='-0.19289999999999682', token='gAAAAABdIK-Xq2i_JTtmCAgsL3pw70l0_G5hsPSi1uhEhO_iwErYZ-cqe7mDICNaLYj7wMUGZzEA3tDsBbAyE_riErkwKrzPPJ8w363oWEz0DOSYEvxIKDRNYycixAONSA_sOukkBilO', msg=<Message.CLOSER: 1>)
Result(lat='51.49199999999477', lon='-0.1929999999999968', token='gAAAAABdIK-Y02yDXsyG37CbeJmkhv053cupB9Mgpy8XNAi72IaB4ro68yzzQMNRfPLErA2ZlCijgeheV7bpVL5ryNoGWRbWlZELl8LXfzMZKnkV-d00ZwPzfPPbCEnaX6EwP7fvr1Ui', msg=<Message.FURTHER: 2>)
Changing direction . . .
New direction: (0, 1)
Result(lat='51.49199999999477', lon='-0.19279999999999684', token='gAAAAABdIK-aeLoaNpSPaScaWhPwg1fXrHgLybBP0pPHYIJJPTpuxm3xpawa9JzINzptVomDPemDOsWU-UsPT5nx0P7yCbHsqOG1BqCPhv_mbdPF2H0fWyk8TUtx5W13jc965OOOd43Z', msg=<Message.FURTHER: 2>)
Changing direction . . .
Congratulations, you made it, here is the flag:  CTF{Who_is_Tardis_Ormandy}
Congratulations, you made it, here is the flag:  CTF{Who_is_Tardis_Ormandy}

Using this service, we can plot the coordinates on a map and see the route we took: