Ceci est une ancienne révision du document !
Exploit 200 points http://quals.nuitduhack.com/challenges/view/9 http://updator.challs.nuitduhack.com/
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?
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.
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 ?
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