Outils d'utilisateurs

Outils du Site


ndhquals2015:updator

Ceci est une ancienne révision du document !


Table des matières

Updator

Énoncé

Unhackable : “Not hackable; that cannot be hacked or broken into.” We manage updates and thus have fixes, this is not a PS3 as it is unhackable … or is it?

challenge

On arrive sur une page avec une interface de login dont on ne possède aucun credentials et un bouton Update. Lorsque l'on clique sur ce bouton, la page http://updator.challs.nuitduhack.com/update.py nous affiche le message suivant : The update managing system is still under construction but will be available soon.

robots.txt

Le fichier robots.txt révèle la présence du dossier temp/ :

  Disallow: temp/*

Dans se dossier on trouve un fichier log.py.encrypted. Comment peut on le déchiffrer ?

pyc

Le bouton Update appel un fichier update.py. On se dit que peut être il y a une fichier .pyc, la page http://updator.challs.nuitduhack.com/update.pyc permet effectivement de télécharger un fichier python compilé. On décompile le fichier avec https://github.com/wibiti/uncompyle2 :

  import config
  import sys
  KEY = config.KEY
  
  def xor(*args):
      if len(args) < 2:
          sys.exit(0)
      length = len(args[0])
      for arg in args:
          if len(arg) != length:
              sys.exit(0)
          length = len(arg)
  
      cipher = args[0]
      for arg in args[1:]:
          cipher = ''.join([ chr(ord(arg[i]) ^ ord(cipher[i])) for i in range(len(arg)) ])
  
      return cipher
  
  
  class Crypto:
  
      @staticmethod
      def encrypt(file):
          with open(file, 'r') as fd:
              content = fd.read()
          content = content.ljust(len(content) + (8 - len(content) % 8), '0')
          blocks = [ content[i * 8:(i + 1) * 8] for i in range(len(content) / 8) ]
          with open('%s.encrypted' % file, 'w') as fd:
              encrypted = []
              for i in range(len(blocks)):
                  if i == 0:
                      encrypted.append(xor(KEY, blocks[i]))
                  else:
                      encrypted.append(xor(KEY, blocks[i], encrypted[i - 1]))
  
              fd.write(''.join(encrypted))
  
      @staticmethod
      def decrypt(file):
          with open(file, 'r') as fd:
              content = fd.read()
          blocks = [ content[i * 8:(i + 1) * 8] for i in range(len(content) / 8) ]
          with open('.'.join(file.split('.')[:-1]), 'w') as fd:
              plain = []
              for i in range(len(blocks)):
                  if i == 0:
                      plain.append(xor(KEY, blocks[i]))
                  else:
                      plain.append(xor(KEY, blocks[i], blocks[i - 1]))
  
              fd.write(''.join(plain).rstrip('0'))
  
  
  print 'Content-Type: text/html'
  print '\n<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset="UTF-8">\n    <title>Updator - Update system</title>\n    <link rel="stylesheet" href="static/font-awesome/css/font-awesome.css">\n    <link rel="stylesheet" href="static/css/style.css">\n  </head>\n  <body>\n    <div id="info">\n      The update managing system is still under construction but will be available soon.\n    </div>\n  </body>\n</html>\n'

On connait maintenant l'algorithme utilisé pour chiffrer le fichier log.py.encrypted : du chiffrement XOR par bloc de 8 caractères. Il ne nous manque que la clé. Bruteforcer 8 caractères nous prendrais trop de temps, il nous faut une autre méthode. Le fichier étant du python il est fort probablement que la première ligne commence par 'import '. Regardons ce que ça donne

ndhquals2015/updator.1428319134.txt.gz · Dernière modification: 2017/04/09 15:33 (modification externe)