TravelEndpoint: 2025
Last updated
Last updated
"This challenge immerses participants in a simulated booking API environment, testing their ability to discover and exploit authorization flaws and misconfigurations. Participants will navigate real-world API security scenarios, including unauthorized data access and privilege escalation. They will work towards uncovering the hidden flag by strategically analyzing API requests, understanding the back-end logic, and chaining multiple vulnerabilities. The challenge emphasizes critical thinking and a hands-on approach to API security assessment, requiring precision and creativity to bypass protections and achieve the final objective."
CWE-639: Authorized Bypass Through User Controlled Key
Broken Object Level Authorization (BOLA)
Insecure Direct Object Reference (IDOR)
CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes
Mass Assignment
CWE-918: Server Side Request Forgery (SSRF)
Fuzzing web apps with Ffuf
jwt.io
curl
Burp Suite
Hashcat
Broken Object Level Authorization(BOLA)
Mass Assignment
Insecure Direct Object Reference
Server Side Request Forgery
bash scripting
we are provided user/guest credentials to start from an authorized pov
alice:Alice@123
Given the description of the challenge and the airplane logo it looks like a normal airline site
I ignored the hint to not waste time brute forcing users/passwords
the source code reveals how the web app is handling login requests to /api/auth/login
after logging in the user is set a JWT and is redirected to /dashboard
testing login using our credentials
jwt in the data portion of the http response
the source code revealed some interesting api endpoints that we could play around with
whenever we want to go to a certain endpoint (e.g. /api/bookings) it checks if we have a valid jwt in the Authorization header of our request, if we don't it simply logs us out
testing /api/bookings using our/alice's jwt
other than the endpoints found earlier we also have /api/fetch
i tried changing the user_id value to 2 to see if we can gain access to another user's data, but we got the error "Invalid Token"
if we try to crack our jwt's secret using a wordlist like rockyou we get the secret "supersecret"
we can now generate a valid jwt for any user using this secret
if we make a request to /api/bookings using user_id : 2 jwt we get 200 OK, meaning it's a valid token
To verify that user_id : 2 is an admin we can analyze the error messages when making requests to /api/fetch, using user_id : 1 jwt we get "Unauthorized: admin access required"
But when using a valid user_id : 2 jwt we no longer get the admin access required error, so this must mean that user_id : 2 is the admin
at this point we have:
a list of /api endpoints
the secret to create valid jwt's for any user, especially the admin user, user_id : 2
/api/fetch endpoint that is only accessible to the admin
I didn't really think about this endpoint until i researched/studied a bit more, and it turns out this is a common endpoint for some APIs
or you could've used a fuzzed using a wordlist of common api endpoints(not sure why it didnt show up earlier, maybe i should've waited a bit longer)
All of these endpoints really stand out, especially the /api/admin/reports(which we will look at later), but another one that stands out is /api/users/{id} that reveals user details by ID
if we request our own information it reveals our email, id , and password hash
But what if we try requesting the admin information?
a BOLA vulnerability!
meaning we could request this information as any user
no authorization checks on who is requesting said information
fuzzing for all possible/existing users
8 users
i got curious as to what the /api/users/update endpoint does
maybe we can update our user's role to admin?
Mass Assignment vuln!, we are now admin
now that we are admin we can access endpoints like /api/admin/reports
you could've also used a valid admin jwt using the secret and user_id: 2
At this point:
you can use a valid admin jwt token by generating one in jwt.io using the secret
or you're an admin after exploiting the mass assignment vulnerability
/api/fetch returns error Admin access required when you make a request with an invalid admin token
but when you make a request with a valid admin token you get the error below
As with any other SSRF vulnerability i did try fuzzing for internal ports but nothing
so i instead tried fuzzing for url parameters and i got
/api/fetch?url=<value>
if we try to make the web app fetch its own source code, it works!, ssrf verified
and of course, the classic /etc/passwd, most are /nologin, so we are not meant to get a shell or RCE via an internal service in this case
Right? i couldve gone for the Werkzeug console pin exploit, but none of the users have some form of a login shell
another secret information disclosure
i tried a random POST request to /api/bookings to see if i can get some valuable error messages
and i did! the werkzeug console/debugger error message returned the app location /app/app.py
another secret disclosed
this is kind of cheesy but this is how i got the ssrf flag(other alternatives paths are mentioned towards the end)
Initially, this was the first flag i discovered while i was playing around with the JWT and cracking the secret
but by using the secret we can create valid tokens for other users and request their information bookings,transactions etc as that user
a script i wrote after solving that automates the challenge
Crack JWT secret OR Information Disclosure via the Werkzeug Error leaking the Secret
Escalating to Admin Privileges
Using the secret to get a valid jwt with id:2
OR abusing the mass assignment vuln to give ourselves the admin role
I couldn't see any other way of getting the ssrf flag without the Werkzeug error revealing the app source code location /app/app.py, unless you fuzzed for files or had a luck guessing /tmp/flag4.txt, or fuzzed for the source code location first