Brandon T. Elliott

home

CTF Writeup: picoCTF 2023 - "Java Code Analysis!?!"

The CTF

picoCTF 2023 took place from March, 14th, 2023 to March 28th, 2023.

The Challenge

This web exploitation challenge began with the following description:

java-code

Downloading the source code gave us bookshelf-pico.zip which we could unzip in order to analyze.

We were also provided the credentials user:user for logging into the website, which after logging in, we were presented with the following:

website

The Flag Book

The book of interest is the flag book which appears to require the Admin role in order to read it.

flag-book

My initial thought was to capture a request with Burp Suite in order to get a better understanding of how the authorization is being handled.

The Bearer

In our captured Burp Suite request on line 7, we see that the website is using bearer tokens for authorization:

burp-request

A recursive grep of the unzipped source code using grep -r token gives us our next lead:

grep

It appears that the website is generating and using JWT tokens, which means that we could potentially be able to create our own JWT token in order to change our authorization level to that of the Admin role.

We need to take a look at the JwtService.java source code next.

JwtService

The JwtService source code seems straightforward enough, and we quickly spot line 27 which is where the SECRET_KEY is being generated:

jwt-service

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.

Not So Random

secret-generator

In this source code, it appears that it first attempts to read the key from a local file server_secret.txt, but if the file doesn’t exist, then it instead uses a hardcoded “random” string of 1234 instead.

We can likely make a safe assumption here that we won’t be able to access this file and that it also won’t exist on the server, so we can continue under the premise that the SECRET_KEY is going to be 1234.

Now, we can use this to attempt to encode our own JWT token, but first we should decode the one we already have.

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.

jwt-decode

The Modified Payload

We already know from the error message that we need the role to be Admin.

However, we likely will need to also modify the userId and email fields as well, which we don’t currently know.

A recursive grep of the source code for the word admin shows a comment within Role.java which may be good enough…

grep2

Inspecting the Role.java source code gives us a hint that the higher the value, the more the privilege:

role.java

We will infer based on this comment and increment the userId field to 2.

In our recursive grep, we also see a line .setEmail("admin") so we will go ahead and set the email field to admin just in case this is needed as well.

We also already know from earlier that we should be able to use 1234 as the SECRET_KEY.

With all of this information, we can now encode a new JWT token using jwt.io again.

JWT Encode

jwt-encode

With our new JWT token, we should be able to replace this easily by inspecting the page and navigating to the Storage section, then Local Storage:

inspect

Now we just need to copy and paste our newly created JWT token into the auth-token section and also replace token-payload with our new payload details.

With this in place, all that’s left to do now is refresh the page and read…

The Flag Book

flag