[Web] Fare Evasion
Description
SIGPwny Transit Authority needs your fares, but the system is acting a tad odd. We’ll let you sign your tickets this time! https://fare-evasion.chal.uiuc.tf/
Analysis
The challenge does not provide source code. Diving into the application and viewing the page source hints at SQL Injection and md5 encoded as latin-1 instead of hex.
After playing around the app, we know that:
- It uses JWT tokens and provides the passenger signing key
- There is an SQL Injection through the kid header with md5 and uses latin-1 encoding due to response
- We have to get the admin key or in this case conductor key to sign our token to advance
Solution
Googling around I found this article which explains the problem and is similar to the challenge (https://cvk.posthaven.com/sql-injection-with-raw-md5-hashes).
Changing the kid header to 129581926211651571912466741651878684928 will leak the conductor key. After getting this key, we can forge our token to obtain the flag.
Payload
1 | //JWT with kid header hash value |
[Web] Log Action
Description
I keep trying to log in, but it’s not working :’( http://log-action.challenge.uiuc.tf/
Analysis
The challenge provides source code and and by running npm audit, it uses an older version of nextjs that is vulnerable to SSRF. Googling for the outdated version provides us with a blog by Assetnote (https://www.assetnote.io/resources/research/digging-for-ssrf-in-nextjs-apps).
The /login condition satisfies the requirements of redirection and ‘use server’. Lets try to hit this.
1 | "use server"; |
However, the redirection can only be triggered by logging in as the admin. This is not possible unless we are extremely lucky.
1 | export const { auth, signIn, signOut } = NextAuth({ |
Solution
While the /login condition is unexploitable, the /logout endpoint which at first glance can only be done after logging in is not protected by the auth middleware. As we can see, the auth middleware only checks for paths with ‘/admin/‘.
1 | export const config = { |
Thus, we can now use the /logout endpoint to solve the challenge as it satisfies the conditions and is accessible.
1 | <form |
Payload
Following the steps, our server is hosted with ngrok and URL to read is http://backend/flag.txt.
1 | from flask import Flask, Response, request, redirect |