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