picoCTF- Java Code Analysis !?!
Description
BookShelf Pico, my premium online book-reading service. I believe that my website is super secure. I challenge you to prove me wrong by reading the ‘Flag’ book! Here are the credentials to get you started:
So we were given credentials for a user account that is “free”. The website contains three books, and “free” users can only read one, whereas premium users, including free, premium, and administrators, can read one each.
We are obviously not allowed to read the “Flag” book; we must be administrators.
The Flag Book
The flag book is of particular interest, and it appears that reading it requires the Admin role.
Hints revolve around tampering with JWT tokens and digging through source files to generate a new JWT token.
The source code clearly shows that the website uses JWT tokens to authorize users and grant access to books based on their roles.
Jwt Service
The JwtService source code seems straightforward enough, and we quickly spot line 27 which is where the SECRET_KEY is being generated:
This is something that we will need to know in order to encode our own JWT tokens, therefore we need to take a look at the source code for the SecretGenerator
class next.
According to this source code, it first tries to read the key from a local file called server_secret.txt; however, if the file is not found, a hardcoded “random” string of 1234 is used in its place.
Here, it’s probably safe to assume that neither we nor the server will be able to access this file, so we can move forward with the assumption that the SECRET_KEY will be 1234.
We should first decode the JWT token we currently possess before attempting to encode our own using this.
Jwt Decode
We can use the website jwt.io in order to decode and encode JWT tokens.
Copying and pasting our current bearer token from the Burp Suite request we captured earlier, we can see the payload of the JWT token.
So, here’s the JWT token in use, so let’s modify it.
The modified payload
The error message already informs us that the role must be Administrator.
We are unsure of the userId and email fields, though we will probably also need to change them.
A comment in Role.java is revealed from the source code for the word admin, and it might be sufficient enough.
Inspecting the Role.java source code gives us a hint that the higher the value, the more the privilege:
Based on this comment, we will deduce and set the userId field’s value to 2.
Additionally, as we already know from before, 1234 should to work as the SECRET_KEY.
Now that we have all of this information, we can use jwt.io to encode a new JWT token.
Jwt Encode
With our new JWT token, we should be able to replace this easily by inspecting the page.