Carbender#
Helpers#
import os
import requests
from datetime import datetime, timedelta
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.environ["API_KEY"]
URL_QUERY = "https://%s.crucible.dreadnode.io/score"
URL_FLAG = "https://crucible.dreadnode.io/api/challenges/%s/submit-flag"
CHALLENGE = "carbender"
def query(data):
response = requests.post(
URL_QUERY % CHALLENGE,
headers={ "X-API-Key": API_KEY },
json={ "bookings": data }
)
return response.json()
def submit(flag):
response = requests.post(
URL_FLAG % CHALLENGE,
headers={ "X-API-Key": API_KEY },
json={ "challenge": CHALLENGE, "flag": flag }
)
return False if response.status_code != 200 else response.json().get("correct")
Solution#
If we submit a booking for 2023-05-29
(a Monday) we can see that the car rental prices are fairly consistent with the only differences for a single car type being that weekend bookings are more expensive.
data = [
{ "car_type": "luxury", "date": "2023-05-29", "action": "book", "created_date": "2022-05-01", }
]
query(data)["prices"]
{'sedan': {'2023-05-29': 119.0,
'2023-05-28': 139.0,
'2023-05-27': 139.0,
'2023-05-26': 119.0,
'2023-05-25': 119.0,
'2023-05-24': 119.0,
'2023-05-23': 119.0},
'suv': {'2023-05-29': 159.0,
'2023-05-28': 179.0,
'2023-05-27': 179.0,
'2023-05-26': 159.0,
'2023-05-25': 159.0,
'2023-05-24': 159.0,
'2023-05-23': 159.0},
'luxury': {'2023-05-29': 189.0,
'2023-05-28': 209.0,
'2023-05-27': 209.0,
'2023-05-26': 189.0,
'2023-05-25': 189.0,
'2023-05-24': 189.0,
'2023-05-23': 189.0}}
However, if we submit and cancel a booking on a Monday prior to 2023-05-29
we can see that the booking price for 2023-05-29
will decrease slightly.
data = [
{ "car_type": "luxury", "date": "2023-05-22", "action": "book", "created_date": "2022-05-01", },
{ "car_type": "luxury", "date": "2023-05-22", "action": "cancel", "created_date": "2022-05-02", },
]
query(data)["prices"]
{'sedan': {'2023-05-29': 119.0,
'2023-05-28': 139.0,
'2023-05-27': 139.0,
'2023-05-26': 119.0,
'2023-05-25': 119.0,
'2023-05-24': 119.0,
'2023-05-23': 119.0},
'suv': {'2023-05-29': 159.0,
'2023-05-28': 179.0,
'2023-05-27': 179.0,
'2023-05-26': 159.0,
'2023-05-25': 159.0,
'2023-05-24': 159.0,
'2023-05-23': 159.0},
'luxury': {'2023-05-29': 186.54,
'2023-05-28': 209.0,
'2023-05-27': 209.0,
'2023-05-26': 189.0,
'2023-05-25': 189.0,
'2023-05-24': 189.0,
'2023-05-23': 189.0}}
We are allowed to book and cancel up to seven times so we can repeat this process for seven Mondays prior to 2023-05-29
to decrease the price as much as possible. This will give us the flag.
date_booking = datetime.strptime("2023-05-29", "%Y-%m-%d")
date_create_booking = "2022-05-01"
date_create_cancel = "2022-05-02"
data = []
for weeks in range(1, 8):
date_booking_new = (date_booking - timedelta(weeks=weeks)).strftime("%Y-%m-%d")
data.extend([
{ "car_type": "luxury", "date": date_booking_new, "action": "book", "created_date": date_create_booking, },
{ "car_type": "luxury", "date": date_booking_new, "action": "cancel", "created_date": date_create_cancel, }
])
response = query(data)
print("Flag accepted:", submit(response["flag"]))
Flag accepted: True