notes
What are JWTs?
JSON web tokens (JWTs) - standarized format for sending cryptographically signed JSON data between systems
contain any kind of data but are most commonly used to send information ("claims") about users as part of authentication, session handling and access control mechanisms
JWT format
3 parts:
header
,payload
andsignature
separated by dotheader and payload parts of a JWT are just base64url-encoded JSON objects
header contains metadata about the token itself, while the payload contains actual claims about the user
eg -
header part is decoded as follow
payload part
security of any JWT-based mechanism is heavily reliant on the cryptographic signature
JWT attacks
user sending modified JWTs to the server in order to achieve a malicious goal
goal is to bypass authentication and access controls by impersonating another user who has been authenticated
impact - severe
Exploiting flawed JWT signature verification
by design, servers don't store any information about the JWTs that they issue and instead each token is an entirely self-contained entity
one problem is that server doesn't know anything about the original contents of the token or even what the original signature was
if the server doesn't verify the signature properly, the attacker can chage the rest of the token
Accepting arbitary signatures
the application doesn't verify the signature part at all
just change the payload parameters and it works
Accepting tokens with no signature
in header part, it looks like :
"alg" parameter is set to
none
->unsecured JWT
servers usually reject tokens with no signature
but this kind of filtering relies on string parsing, and can bypass by using classic obfuscation techniques such as mixed capitalization and unexpected encodings
Brute-forcing secret keys
some signing algorithms such as HS256 (HMAC + SHA-256) use an arbitary standalone string as the secret key like password and this secret can't be easily guessed or brute-forced by an attacker
otherwise, they may be able to create JWTs with any header and payload values and use that key to resign the token with a valid signature
sometimes, develpers make mistakes like forgetting to change default or placeholder secrets, or copy and paste code snippets they find online
use
hashcat
to burte-force
JWT header parameter injections
only
alg
header is mandatorybut JWT header (JOSE header) often contain several other parameters
eg -
jwk
(JSON Web Key) - provides an embedded JSON object representing the keyjku
(JSON Web Key Set URL) - provides URL from which servers can fetch a set of keys containing the correct keykid
(Key ID) - provides an ID that servers can use to identify the correct key in cases where there are multiple keys to choose from
Injecting self-signed JWTs via jwk
JWK - standarized format for representing keys as a JSON object eg -
ideally, servers should only use a limited whitelist of public keys to verify JWT signature
but, misconfigured servers sometimes use any key that's embedded in the
jwk
parameterexploit by signing a modified JWT using your own RSA pirvate key, then embedding the matching public key in the jwk header
Injecting self-signed JWTs via jku parameter
instead of using the jwk header parameter, some servers let you use the jku (JWK Set URL) header parameter to reference a JWK Set containing the key
JWK Set - JSON object containing an array of JWKs representing different keys
JWK Sets are sometimes exposed publicly via a standard endpoint
/.well-known/jwks.json
more secure websites will only fetch keys from trusted domains, and can bypass like SSRF bypass
Injecting self-signed JWTs via the kid parameter
header of JWT may contain a
kid
(Key ID) parameter, which helps the server to identify which key to use when verifying the signatureVerification keys are often stored as a JWK Set
the server may simply look for the JWK with the same
kid
as the tokenkid
was not defined a concrete structuredevelopers might use the
kid
parameter to point to a particular entry in a database, or even the name of a fileif this parameter is also vulnerable to directory traversal, an attacker can potentially force the server to use an arbitary file from its filesystem
if the server supports JWTs signed using symmetric algorithm, it is dangerous
one simplest methods is in Linux server use
/dev/null
path, which is an empty file and fetching it return null and signing the token with a Base64-encoded null byte will result a valid signature
Other JWT header parameters
cty
(Content Type) - to declare a media type for the content in the JWT payload; if you found a way to bypass signature verification, you can try injecting acty
header to change the content type totext/xml
orapplication/x-java-serialized-object
which can enable new vectors for XXE and deserialization attacksx5c
(X.509 Certificate Chain) - can be used to inject self-signed certificates similar to the jwk header injection (CVE-2017-2800, CVE-2018-2633)
JWT algorithm confusion
known as key confusion attacks
occur when an attacker is able to force the server to verify the signature of a JSON web token using a different algorithm than is intended by the developers
Symmetric Vs Asymmetric
JWT can be signed using different algorithms
eg - HS256 (HMAC + SHA256) use a symmetric key means the server uses a single key to both sign and verify the token
![[Pasted image 20221101205841.jpg]]
other algorithms such as RS256 (RSA + SHA256) uses asymmetric key pairs which contains a private key which the server uses to sign the token and a mathematically related public key that can be used to verify the signature
![[Pasted image 20221101210036.jpg]]
Performing algorithm confusion attack
Obtain the server's public key
Convert the public key to a suitable format
Create a malicious JWT with a modified payload and the alg header set to
HS256
Sign the token with HS256, using the public key as the secret
Step 1. Obtain the server's public key
servers sometimes expose their public keys as JSON Web Key (JWK) objects via endpoint such as
/jwks.json
or/.well-known/jwks.json
and they may be stored in an array of JWKs calledkeys
and known asJWK Set
Step 2 - Convert the public key to a suitable format
version of the key that you use to sign the JWT must be identical to the server's local copy and every signle byte must match including any non-printing characters
In Burp
In JWT Editor Keys tab,
New RSA
> paste the JWK that was obtained earlierSelect the
PEM
radio button and copy the resulting PEM keyin Decoder Tab,
Base64-encode
the PEMin JWT Editor Keys,
New Symmetric Key
>Generate
replace the generated value for the
k
parameter with a Base64-encoded PEM key that was copied and save the key
Step 3 - Modify your JWT
modify the JWT as you like and make sure the
alg
header toHS256
Step 4 - Sign the JWT using the public key
Sign the token using the HS256 algorithm with the RSA public key as secret
Last updated