It’s another Juice Shop challenge. This one involved JSON Web Tokens:

Forge an essentially unsigned JWT token that impersonates the (non-existing) user jwtn3d@juice-sh.op.

As far as I knew, JWTs were a way to determine authorization between a user and a web server, without the web server needing to keep track of sessions.

I had honestly forgotten what they looked like though, and after watching a few Youtube videos, I knew it’d be a Base64-encoded token that included three parts (header, payload, and signature) and was separated by periods. So I decided to see what happened when a user on the Juice Shop site logged in.

I observed the user Amy being given a token after logging in (via SQL injection):

Logging In

And when I looked at a simple query using the Juice Shop search bar as the user, I could see the same token was in the bearer authorization header:

Auth header

That looked promising. I went to the site jwt.io, to decode the token. I could see the header, the payload, and that the signature was using asymmetric encryption:

Header and payload

Signature

The challenge mentioned an unsigned token, so my guess was that meant that it really wouldn’t matter to the server if the token was signed or not.

I went to CyberChef and started to modify and re-encode the token. First, I changed the header. For the algorithm JSON field I put “none”:

Editing header

I pasted the header in a text editor, and was careful to get rid of the Base64 padding (the = sign). And then for the payload I put jwtn3d@juice-sh.op as the email:

Editing payload

I pasted that in a text editor as well. I then put the two strings together, separating them by a period. I took that search bar query I had made as the user and sent it to Repeater in Burp Suite, and then I deleted the original token in the bearer header and replaced it with my new one.

For some reason, it wasn’t working after I submitted it a few times. After a bit more digging I realized I also had to put a period at the end of the token for it to work. It’s really important when modifying these tokens to remember the periods and to leave out the Base64 padding. After I added the period to the end of the token it worked, and it was confirmed that the server was accepting unsigned JWT tokens:

Challenge completed