Thomas DEVerson - NahamconCTF 2024
About the challenge
NahamCon CTF 2024
The web application is running a python flask web server. On /status
, we can see the total uptime of the application
On /backup
, partial source code was disclosed:
According to the source code, the three allowed users were Jefferson, Madison, and Burr. Additionally, the flask secret is the concatenation of THE_REYNOLDS_PAMPHLET-
and the current time when the application was initialized. According to the uptime, the application was initialized sometime during 1797.
The flask signed session format is seen below:
Calculating the secret
If the secret was initialized at the same time the application went online in 1797, we could calculate it by subtracting the total uptime to the current time. I made the following python script that calculates the secret:
1
2
3
4
5
6
7
8
9
10
11
12
from datetime import datetime
from dateutil.relativedelta import relativedelta
import requests
r = requests.get('https://challenge.nahamcon.com:32197/status')
data = r.text.split()
days = int(data[4])
hours = int(data[6])
minutes = int(data[8])
print((datetime.now() - relativedelta(days=days, hours=hours, minutes=minutes)).strftime("%Y%m%d%H%M"))
The output of the above script would consistently be 1797/08/15 16:45, which translates to THE_REYNOLDS_PAMPHLET-179708251645
in secret format.
However, the calculated secret was incorrect and did not match the signature of the cookie. This was may be due to a delay on the application’s shown uptime and the real date on when the secret was initialized.
So, I made a script that generates a wordlist of all possible secrets possible during the day 1797/08/25:
1
2
3
4
5
6
x = 179708250000
for j in range(x, x+9999):
with open("secrets.txt", "a") as secrets:
secrets.write('THE_REYNOLDS_PAMPHLET-'+str(j)+"\n")
print('done')
Using the generated wordlist, the secret key of the signed session was bruteforced using flask-unsign
and yielded the following result:
The correct secret is THE_REYNOLDS_PAMPHLET-179708250845
There was an exact 8 hours interval from the initialization of secret and the application’s supposed initialization date shown in its uptime
Using the now obtained secret, I forged a cookie that sets my user to Jefferson
Using the now forged cookie, I visited the /messages
route to obtain the flag: