Disclaimer!!!
The information provided in this blog is to be used for educational purposes only. All of the information in this blog is meant to help the reader to develop a hacker defense attitude in order to prevent the attacks discussed. In no way should you use the information to cause any kind of damage. Hacking is a crime and I am not responsible for the way you use it.
Welcome back to the fourth part of ZTH room on tryhackme. Today we will learn how we can leverage our privileges using None value in JWT token. I assume that you have some basic knowledge about how JWT tokens work. If not, please see one of my previous blog post about JWT: https://hacking4everyone.com/tryhackme-web-fundamentals-authenticate-part-2. As with the previous post, I will just paste here my notes I made during the room and say few words about it.
Intro
There is actually three possible algorithms, two of them RS256 and HS256 which we have already studied. There is a third algorithm, known as None. According to the official JWT RFC the None algorithm is used when you still want to use JWT, however there is other security in place to stop people from spoofing data.
An attacker can switch to the None algorithm, in the same way one switches to RS256 or HS255, and have the token be completely valid without even needing to calculate a secret.
Manual exploitation
Instead of repeating myself, I would rather recommend checking one of my previous blog posts: https://hacking4everyone.com/tryhackme-web-fundamentals-authenticate-part-2/
And if you are lazy to read that, I will also show you how the manual exploitation works real quick:
Let’s say we are logged in as a low privileged user (longz) in the webapp:
In the browser, navigate to: Storage -> Cookies
As the screenshot above shows, the JWT token has been assigned to our session with the following value:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdXRoIjoxNjIwMTcwOTE2OTM2LCJhZ2VudCI6Ik1vemlsbGEvNS4wIChYMTE7IExpbnV4IHg4Nl82NDsgcnY6NzguMCkgR2Vja28vMjAxMDAxMDEgRmlyZWZveC83OC4wIiwicm9sZSI6InVzZXIiLCJpYXQiOjE2MjAxNzA5MTd9.sJV1WL0-0b_07qetM6PUUCPMNFZqfg5KFgelM7zEqyA
Now we need to decode this. So navigate to jwt.io and put it there to see its decoded value real quick:
As you can see from the above, the type of the token is JWT, the alg value is set to HS256 and the purple text shows the payload – informing us about the role we possess.
So let’s change the alg value to „None“ and the role value to „admin“. So the first part will look like:
eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0
and the second part as:
eyJhdXRoIjoxNjIwMTcwOTE2OTM2LCJhZ2VudCI6Ik1vemlsbGEvNS4wIChYMTE7IExpbnV4IHg4Nl82NDsgcnY6NzguMCkgR2Vja28vMjAxMDAxMDEgRmlyZWZveC83OC4wIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNjIwMTcwOTE3fQ
Now put these two parts together, append the dot (.) and that’s it. That’s our final payload. You don’t need to append signature to the token, because we set the alg value to „None“. It means that no encryption has to be used. Therefore, we don’t need to know the secret which is used for encryption and checking that the message wasn’t changed along the way.
The final payload:
eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdXRoIjoxNjIwMTcwOTE2OTM2LCJhZ2VudCI6Ik1vemlsbGEvNS4wIChYMTE7IExpbnV4IHg4Nl82NDsgcnY6NzguMCkgR2Vja28vMjAxMDAxMDEgRmlyZWZveC83OC4wIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNjIwMTcwOTE3fQ.
Now navigate back to the Storage -> Cookies in your browser and put there the final payload instead of your JWT token:
And when you reload the webpage:
We leveraged our privileges to admin account!
Semi-automated exploitation
If you want to speed up the process, you can use TokenBreaker’s TheNone.py python script that automatically changes the alg value to „None“ and strips the signature part: https://github.com/cyberblackhole/TokenBreaker
TheNone usage:
python TheNone.py -t <JWTtoken>
That’s it for this part. Thank you for reading this and see you at the next blog post!
All credits go to Paradox (https://tryhackme.com/p/Paradox) who has created this excellent room. You can find it at https://tryhackme.com/room/zthobscurewebvulns