old-tickets Writeup
Bruteforce timestamps to find the correct ticket hash and retrieve the flag.
Challenge Description
Accessing the website, we have a simple ticket system. We can input a name and message and submit a ticket, but nothing will happen.
Solution
Step 1: Analyzing the Source Code
To begin, I inspected the source code of the website for any hidden clues and discovered a comment embedded in the HTML:
1
<!-- Our first bug was: d63af914bd1b6210c358e145d61a8abc. Please fix now! -->
This hash is something that could be useful later in the challenge.
Step 2: Intercepting and Examining Requests
When I submitted a ticket, I noticed the server made a GET
request instead of the typical POST
or PUT
. This was unusual behavior for submitting form data.
To further investigate, I used Burp Suite to send an OPTIONS
request to the server, revealing that the server also supports PUT
and POST
methods.
Step 3: Sending a POST Request
Next, I crafted a POST
request using Burp Suite. Upon sending this request, the server returned 500 Internal Server Error
. Analyzing the error response, it exposed a traceback with useful information about the server’s code.
Step 4: Adding a Code Parameter
Following the hints from the error message, I added a code
parameter to the POST
request. After doing so, the server responded successfully, but nothing appeared to change visually on the website. Using the hash d63af914bd1b6210c358e145d61a8abc
found earlier as the code
value resulted in the server telling us to Try harder!
.
Step 5: Identifying the Hash Type
I used the hash-identifier tool and it indicated that the hash was most likely an MD5 hash.
Step 6: Decrypting the Hash
I then navigated to hashes.com and used the hash. The result was an integer, which appeared to be a timestamp.
Step 7: Formulating a Bruteforce Strategy
Realizing that the hash was a timestamp and recalling the server’s message to Try harder!
I deduced that the server required a specific timestamp to generate the correct ticket hash and reveal the flag. This led us to develop a bruteforce strategy: incrementally adjust the timestamp, hash it, and send it to the server until I find the correct one.
Step 8: Writing and Running the Script
With a plan in place, I wrote a Python script to automate the bruteforce process. The script computes the MD5 hash of incremented timestamps and sends them in POST
requests to the server until it retrieves the correct flag.
During bruteforcing, I also encountered a response containing
ctf{Try harder!}
, which required me to adjust the script to continue searching until it finds the actual flag, not just any string that starts withctf{
.
Step 9: Obtaining the Flag
After running the script, it successfully identified the correct timestamp and retrieved the flag from the server.
Script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import requests
from hashlib import md5
import re
url = "http://34.107.71.117:31882"
timestamp = 1628168161
for i in range(1000000):
code = md5(str(timestamp + i).encode('utf-8')).hexdigest()
data = {"code": code}
r = requests.post(url, data=data)
pattern = r'ctf\{[0-9a-fA-F]{64}\}'
match = re.search(pattern, r.text)
if match:
print(timestamp + i)
print(match.group())
break
Flag
1
ctf{4086d9012b250dc1d821340f23b4af9b29d780552434175cb713b6d7502885c9}