Rating:

# Junior-JWT

## Description

Just one of [them](http://junior-jwt.peykar.io)!

## Files provided

A zip file containing a PHP page source code. (You can see extracted files in [source](source/) folder in the repo)

## TL;DR

We should change the algorithm to HS256 and change the role value in jwt to admin and sign it with the given public key.

## Writeup

Looking at the source code, we see a class called JWT that provides encode and decode methods and also some helper functions for URL decoding.

Also there is a main function that runs on startup. It creates jwt cookie with role: guest if it's not present.
if The cookie is present it checks the role attribute, if the role is equal to admin it shows the flag, otherwise it shows the source code.

So we should find a way to modify role value to admin in the jwt cookie but we don't have the jwt secret key. So we should go for potential bugs in the jwt methods.

There can be several famous [bugs](https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/) in jwt custom libraries. The first bug I tried was the none algorithm. But at line 40 the decode function checks for the none algorithm, So this is not the solution.

As we see in main function, the jwt is signed with RS256 algorithm by default. RSA uses public and private key (Asymmetric). The JWT is signed using private key and verified using public key. We can see the public key in the source code but we need the private key for signing our modified jwt.

### The Idea

If we could find a way that server verifies the jwt using the same key that jwt is signed with, we could easily change the role field and sign our jwt using the public key.

In HS256 algorithm, that is a symmetric algorithm, the jwt should be signed and verified using the same secret key. So, if we change the jwt algorithm to HS256, change the role value to admin and sign it with the public key, the server will also verify the jwt using public key.

## Solution

For creating the payload, we can use the website's source code.

We should just change the main function as below (changing role to admin and changing RS256 to HS256):


function main()
{

$publikKey = '-----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEApPRW0nXMoQyN8GzVCHaW nWyq00omHh/o7AXEJvbpVBk5HTWLt+Zdj1aK1JFWU5lPeMSoXkf7WJiqoGgwVblX Rq2dSIIaNBFSjomS1Mcw1Tyx+q9Y6CPJGdwAMEMH5uKhGkgV9OrFQcHoozLAvzFl BneqmTO9+V1FKEuHWHItvdP1em7UiUnZ7JXb13L4IbZVGPNgDVf0GoButIlVo1+T pMZcBHNV0ndGZg0e6qTCp5m9yMWcH697Rt2FRN4fgJpYBknBs8UrAeCczRkk6037 N+c4IM+St6KZNqg+4ZlRZC+V9zOBSTkrXXN/CXRUiIQMgmyit5zbEpN8PUY6VPzk zVI9FbkB0nb+Dp04VPRWeeV1IKPZk2DuSOALh9ZacbEQ8Spuua6nxZ5gCSve7TL7 r9xg8ml5zZXAw7l8WoHkyy2ocPy0OL+PWFvUar59epfPUQZmRE08yVrlvy+WXFC2 dbFxD80tPgbcjJbKRGGv1uOx/3Z2HrXHoOslVmV87rgWfxBaJjrSsSY1fKLYJLnk FKJd6eSLDYzTAczbMiov8F9ovMw4/juWZy2s4QOCdXp7byKOuQUJ+HSiZiNiyjTk XaA5oGEF/FIxAMRbaEd/YSsE7ASMxS4mhyIAGFvqK8YZ+xqEAbNlT4zK+dAAC3mL I/VyHBAlgHRxEiRE860DhfcCAwEAAQ== -----END PUBLIC KEY-----';$issuedAt = new DateTimeImmutable();
$data = [ "role" => "admin", "iat" =>$issuedAt->getTimestamp(),
"nbf" => $issuedAt->getTimestamp() ];$token = JWT::encode($data,$publikKey, 'HS256');

echo \$token;

}



It will print the the JWT payload that we should put in jwt cookie and request GET / to get the flag.

## Flag

S4CTF{7h3r3__iS_s733L_a_bUnch3__0u7_th3r3!!!}

Original writeup (https://github.com/ali-em/writeups2021/tree/main/S4CTF/junior-jwt).