
[Music]
hi everyone a lot of people today I actually didn't really expect that so that makes me a bit nervous um but anyways um my name is Victor um I'm 28 years old and I'm a senior penetration tester at all cyber uh where I mainly test web applications and apis I also do Network penetration testing uh recently mobile applications and all other things related to cyber security uh I was also a speaker at OAS Bulgaria chapter where I spoke about dependency confusion attacks um and at soft cyber security Summit where I basically spoke about basic web application attacks and recently I'm also a lecture at sof Toni um I have the following certification s which are
junior penetration tester and the V2 version uh related to network attacks and basic we web application attacks uh web application penetra penetration tester and penetration tester extreme uh certified applications uh security uh practitioner and and others uh also in my spare time I'm a back Bounty Hunter on several platforms and I use Medium as my kind of person block where I can uh share all my findings uh in The Bu Bounty World um so uh today's talk is not going to go without some Basics uh so I'm going to try to break down Json web tokens first and then we're going to kind of Deep dive into cryptography and potential mistakes that we can see so U Json web token JWT or jot uh
we'll look also at Jose which are basically JavaScript object signing and encryption which is basically a set of Open Standards which defines the Json web algorithms Json web encryption Json web signature and Json web keys so uh we'll Deep dive as I said into Json web tokens um we'll basically have a look at three uh modern classes of J Json web token attacks and these attacks you'll probably not see in any manual yet uh because they are kind of recent disos kind of recently so this security research can give you a head start in your penetration test or if you're a bug bounty hunter or if you're interested at all in ethical hacking uh so we'll talk about sign encrypt
confusion and polyot tokens uh both allow you authentication and authorization bypasses or a complete token forgery and we'll also talk about the billion hush sat which can be used uh for an application Level denal of service again to token processing servers so um let's look at a basic Json web to uh this one is a in its most basic form we have the J header which defines the algorithm in this one there is no algorithm being used which was actually related to a lot of vulnerabilities that we seen with Json web tokens it's quite a famous attack but it's actually part of the RFC and this means that the Json web token is basically not
secured um well we also have the payload um and uh the payload basically contains our claims claims are basically statements about a given entity and in most of the cases uh the claims are the entity is basically as the user uh so what is a Json web token it's basically a compact URL safe means of representing claims to be transferred between two parties as simple as that there are two two types of Json web tokens um or at least two primary types uh but we'll see also that there are others uh so we have the Json web signature which is basically digitally signed uh it can be symmetric or asymmetric and we also have Json web
encryption uh where uh the payload or the claims are basically encrypted um so this is a Json web token in a Json web signature format uh we have the Jaa header as we said earlier we specify the algorithm uh in this case it it uses a a hash based message authentication code so with a hushing function so this is a basically symmetric Json web signature using a secret uh we have the Json uh web signature payload the payload is usually always the same it always contains our claims and claims are basically uh a key value pair the key is always a string and the value uh can be any uh Json primitive type uh and then we have the signature in the
Json web signature uh which is basically used to verify that the Json web token was not uh changed during Transit uh when we create the signature we basically basics for URL and called the header the payload and in this case we have a predefined secret alt together uh we use the hushing function to basically create the signature this signature is then basically used to verify uh that uh the Json web token has not been modified um also we have Json web token in a format of Json web encryption so uh in this case we have the header once again uh but we have uh the algorithm and encoding uh both must be present in the header uh because we
we use the algorithm uh to basically calculate the content encryption key or to create the content encryption key key uh and we need the encoding uh to basically encode uh the cipher text or the payload uh and this is how we kind of create a payload I'm not going to go into too many details here uh because this could be probably a lecture in itself um we also have the possibility of having a nested uh Json web token which is usually a Json web signature in a Json web uh encryption so first we create our Json web signature then we take that Json web en uh web signature and we use it as a payload of
a Json web encryption uh basically Cipher text and uh it's kind of technically possible to first uh encrypt and then sign uh but that's that could be an implementation mistake as well uh that's why it's important first sign the Json web token and then encrypt it and last part of theory uh we also have Json web keyset uh which is basically a set of uh it's it's basically ajacent representation of um the public key uh in a asymmetric encryption so in asymmetric cryptography we have public and private key um in open ID connect you'll see basically uh the public key being uh exposed and this is this is how it looks so as I said there is usual a
discover end point where you can see but it's also possible to be calculated uh from uh two Json web tokens so if we have two Json web tokens using asymmetric crypto cryptography we can calculate the the public key uh it has its own properties um I'm not going to go into details uh but the properties will basically have the value of the uh public key and here we're going to go into attack number one uh which as I said is sign and encrypt confusion and before we get into that we need to look at uh three distinct classes of crypto uh cryptographic algorithms uh that we can use so we have hmark uh which is basically uh symmetric
cryptography so you have only a secret uh we also have digital signatures which is public private uh so it's asymmetric cryptography using public and private keys and we have authentic encryption which is how we create Json web encryption so the first two can be used to create Json web signature the last can be used to create Json web encryption object now uh which algorithm class we're going to choose depends on what we want to achieve um any CSP holders or any cissp candidates will know Integrity authenticity confidentiality and non-repudiation so hm digit signatures and authenticated ENC encryption all give you the integrity and authenticity of the data um in authenticated encryption as you said you also have confidentiality
uh which means that the payloads or the claims about a user about an identity or usually us are confidential they're encrypted so they uh they cannot be seen uh which is I guess good if you if you need to put some sensitive data into the claims like a password or something else um but what we actually want to look at here is the non- reputation part and kind of where uh many implementers of uh Json web talken libraries go wrong and it's non-repudiation uh non reputation basically means that the data can be verifiable by by others uh which means that in adjacent web signature using asymmetric cryptography the public key can be used to verify that the
signature has been uh uh is is actually
valid and uh this is kind of where we go a bit into code and uh uh we're going to look at an off FP example and this is all called from their website uh it's not me wening it so we'll kind of break it down uh so we're basically importing the Json web token object from off lips uh library and we create a header in a payload uh the header defines the algorithm rs256 and the payload we have the issuer and the subject which is usually us we can load the private key which reads a PM file um and we encode it using the header the payload and the private key um but how we can verify it we can
basically load the public key that is related to that private key and we can just decode it by taking the whole value of the encoded uh Json web signature and um checking it with the public key um from then we can basically print the claims or print the headers and uh we get basically uh the result uh and we go into the more interesting stuff basically but where we when we decode um in the way that we did here when we load the public key and we decode uh the Json web toen with the public key uh we can basically turn it into the dictionary of the payload and uh what is interesting about this piece of code is that it's actually
insecure uh it's on their website it's part of their documentation but it's insecure um and the issue here is uh that we're basically not looking at the AL algorithm header so uh when we're decoding we can basically uh uh what happens is the library basically look at the algorithm header and based on the algorithm header it will uh it will decide uh how to decode it so you should never combine symmetric and asymmetric signature schemes so your algorithm you should usually have a check whether it's hmac or whether it's asymmetric encryption uh using RSA for example so here we have a function on their website obviously they sell they tell us after this code they say it's
insecure you should be doing that and this is how you can do it for example um so we have a function where we uh take the header and the payload we look look at the header and if it's asymmetric we return the public key if it's symmetric we return the shared key and at the bottom we basically decod uh depending on the header we're either going to use the secret or the public key but let's say that we only want to use digital signatures and we have RSA 256 384 512 which basically uses a different sha hash um but let's change the function a bit so we still do the same that we do here but we know that
we're going to never going to use symmetric encryption because we only have public and private keys so we basically take the header and we check if it starts with RS if it does then we we return the public key and we decode uh the Json web
signature and here uh that's where our vulnerability actually is because yes we will not allow algorithm confusion you'll not be able to load a symmetric key um but what you can do is instead of signing the token we can actually encode it from a jws we can change the values here and turn it into adjacent web encryption object so as you see here we have the Json web signature with your header your payload and your signature we can change those values uh this is basically done using uh JWT editor in burp seed so we encrypt it we take the public key which as I said is public so anyone can get it we use the
public key we change the key encryption algori to RSA oap 256 and we specify the encoding that we're going to use for the Json web encryption object um in the payloads I've already changed roles from user to administrator once we encrypt it we have the following object and that's how Json web encryption looks so we have your header once again and you have your uh payload uh which is now encrypted us using the public key so in this case uh the jtd code function will parse the algorithm header and it allows all RS functions which once again we're still within the category right it still starts with RS and the claims validation is going to
be handled by claims. validate and that's how we actually get the sign encrypt confusion uh vulnerability so what this allows us to do we can basically Forge a token we can create our own claims we can use it to basically become administrators um but the attack has some preconditions so if you want to test it you'll first you need a library that supports asymmetric Json web uh tokens so Json web signatures basically which is almost every Library out there uh the application needs to use Json web signature tokens with public cryptography in our example we used RSA but it can be elliptic curve or any other public U uh public private key cryptography uh and the private key
needs to be accessible by the validation function uh there should be no specific algorithm enforced so if we go back to this piece of code if we only allow rs256 then this attack will not be possible because the algorithm is now not arrest to 56 and that trer should be able to determine the public key so we can either read it for the from the open ID uh connect Discovery endpoint which is wellknown /jw k. Json or we can compute it uh uh basically from two Json web uh signature tokens that was attack number one uh attack number two is a polyl token uh which is actually very interesting but once again we need to go through some
Basics and uh what we need to know is that there are two types of uh uh Json web signature serialization which is Compact and Json Ser realization and then there is also two Json uh two jws jsonc realizations which is general and flattened the compact is what we've been looking at and what you'll probably see almost everywhere and this is how a general J uh Json web signature serialization looks uh where basically you have the payload and the signatures uh to the payload uh represented as a Json object and this is a flattened uh Json serialization where once again you have the payload you have the protected header you have the signature and in this case we also have the uh key ID
which is not necessary but it can be there um so so we have uh interesting scenarios that happen in the wild and it's when you want to transfer securely a Json web token between two different applications now here I've given an example of a um Azure uh where you basically will need to be able to do that uh and I've put some extra reading material if everyone wants to go through it um but I'm going to simplify it like this so let's say that you have a application that takes two libraries two Json web toen libraries you use one library to validate to basically do all the cryptography and you only use uh the second library to do authorization
decisions you can do it for a number of reasons and it actually happens more often than we know so how it works is the the once we once we authenticate we get the Json web token then we'll request the resource we'll return the Json web token in an authorization header Library will look at it and say whether it's uh it can validate it or no so if the signature is correct or no then it will pass it on to the second library and it will tell us whether we're authorized to access let's say the administrator portal and here is actually a piece of code that is example of what I'm talking about where we have J crypto uh which is
the validator so it will basically look at uh the signature and it will verify whether the signature is fine or not so it does all the cryptography um and then we also have python JWT validator that will not do any cryptography it will assume that the head header payload uh have been verified with a signature and it will only look at the claims and tell us whether we authorized to do a specific auction action so how can we exploit this let's say we have an authentic Json web signature in a compact format again algorithm and the payload with our claims in this case we are at John do now what we can do is we can change
the compact Json web signature to a flattened Json serialization format where we basically the protected will be the header the payload will be the payload and the signature will be the signature but on top we'll also add two new key value pairs the first key is going to be once again the header and then the um the value of the header will be a new uh claims payload that we create in this case we create uh new claims with the name of admin we've set the expiry to one month later and uh we've put a new subject uh ID so what happens is J crypto will look at this token that we've provided it and it will ignore unknown Fields so
the first fields are completely ignored and it only looks at the protected the payload in the signature it does the verification and it's all fine we have not modified the original uh Json web signature at all once it verifies it it passes it on to python JWT what python JWT actually does is it will take the header the claims and the signature and it will split it on the dots and it actually uses underscore uh which output here is basically a symbol uh uh commonly used to basically throw away a variable so we're basically not going to use it at all um so what happens uh it ignores all non Basics to characters so that
includes also the um everything that's not in the basics for alphabet so it will it will only leave us with the result at the bottom where we have the header and the newly created uh claims and this way we've basically bypassed uh any authorizations that we were and right now we're basically admin um and yes that is attack number two and attack number three uh which is a bit more basic uh but once again we need to go into uh a few details um so billion hushes uh in this case we're going to look at the Json web encryption um and uh once again with Json web encryption you have three uh different ways uh to basically encrypt you can use
public private key you can use a secret shared key encryption or you can use password based encryption and in this vulnerability we're basically going to look at the password based encryption so how does it work key encryption with password based encryption standard to we basically derive a key from a user supplied password using the PBS to schemes so we can perform encryption of a Content encryption key u as I showed ear earlier in a gwe the content encryption key is used to basically um encrypt the plain text or the claims so uh there are two functions specified in the RFC uh password based key deriv derivation function one and key der derivation function two and the first version is not no longer
supported and is not recommended so many libraries don't use it anymore um but will still look at the uh key derivation function too um now it takes an as an input a password it takes as an input AA and an iteration count uh how it works is the encryption part we take the salt and the iteration count we select the length of the desired key length and we apply all of this to the password the salt and the iteration count um why do we want to do this uh because the more iterations has uh the less it will be Su susceptible to um basically dictionary attacks um so think of it as in let's say Linux
you can have for example 10 iterations on a bcrypt uh hash which means that you'll need more computing power to basically uh um to be able to uh to perform addictionary attack because each password you'll need to encrypt it 10 times to be able to get the same to the same result uh in a decryption so we reverse the process we basically need to provide the salt the iteration count and the password and we uh and the key length and we apply the selected uh function onto the password and that's how we kind of decrypt the cipher text now uh the header parameters actually uh for pbs2 uh use the following uh those those are the header parameters
that are basically used for pbs2 we have once again the encoding uh which we looked at earlier uh we have the algorithm which specifies the algorithm for password-based encryption standard uh with a specific hashing function and we have additional parameter header parameters and these are actually the ones that we'll focus in we have the salt input and the uh the iteration count so as we can see the iteration count represented as a positive Json integer it needs to have a minimum iteration count or of thousand or at least that is recommended and this is actually where our attack comes in it's as simple as that we don't even need to know the token we don't need to know anything
basically we can specify the algorithm we can specify the salt and the encoding and the rest of the Json weapon encryption object can be absolutely bogus strengths uh it can be anything we want because what actually happens here is we specified on the iteration counts a few billion of uh iterations now everyone doing uh some hushing functions will basically know that a few billion of uh iteration counts of a hashing algorithm will basically get a server or computer or anything down quite fast so the server basic can need to compute all those billion hashes in order to be able to uh derive the contenting encryption key before it can determine that the JWT that we've provided or the Json web
encryption is invalid as I said we can be unauthenticated we don't need to have a valid token we don't need anything we just need to pass this as a header basics for EUR all encoded and then provide the rest uh of adjacent uh web encryption and this attack is mainly used again to token processing servers and uh the attack is a not a normal Network denial of service is an application Level denial of service attack um so what was the result of uh all of those vulnerabilities you have the following CVS and the following uh libraries that were affected now we have the sign encrypt confusion three times on offli JW crypto jwx uh which are actually very
famous libraries for Json web tokens um we also have the polyglot token vulnerability on python JWT which is what we actually looked at and we have bil in hash's attack against J and Jose JD um here I've listed the resources uh that I've used uh for uh the presentation so if you like to go ahead and read some of this uh trust me it's very difficult reading takes a lot of time and probably most of you guys will be very bored at looking at rfcs um anyways it's actually quite interesting and I think there is a lot to be learned um but yes uh that was the presentation those were the fre attacks um that uh I wanted to present to you
and as I said if there is any B bounty hunters or penetration testers these vulnerabilities are still almost not seen anywhere