Nuit du Hack 2013 Quals – huge.js

Nuit du Hack 2013 - huge.js - task website

Beim Aufruf der Webseite der “huge.js” – Challenge erschien nach unwesentlicher aber bemerkbarer Wartezeit dieses Bild mit einer eingeblendeten Inputbox. Der Quellcode erstaunlich einfach gestrickt:

<body>
  <div id="panel">
  </div>
  <script src="huge.js" language="javascript"></script>
</body>

Klarer Fall, erstmal die Ressource huge.js runterladen … erster Schock – 25 MB komprimiertes Javascript :-) Na danke!

Nuit du Hack 2013 - huge.js - obfuscated javascript code

Dateianalyse via “SharpEye-Methode” ergab, dass es sich um ein paar wenige Byte JS-Code, dann 99,9999% Hexkrams und ein paar schließende Klammern am Ende der Datei handelte.

Naja, die erste Maßnahme war dann einfach mal den Code zu minimieren, dazu einfach die ersten Zeilen extrahiert und dann noch die letzten Zeilen und hoffen, dass nicht zwischendrin noch ein oder mehrere Codeblöcke sind (kann man aber mit cat huge.js | xxd –c 60 | less wunderbar durchscrollen :-)

Raus kam dann erstmal das hier, was ja schonmal ganz nett aussieht.

Nuit du Hack 2013 - huge.js - javascript code

Bettet man den um den HEX-Krams erleichterte Quellcode dann in ein HTML Dokument small.html ein, dann erhält man zunächst tatsächlich ein valides Dokument mit JS bestehend aus zwei Funktionen d() und x(). Beim Aufruf der Seite erfolgt keinerlei Ausgabe. Fügt man ein document.write(o); in Zeile 12 hinzu, sollte es eigentlich zu einer Ausgabe kommen – wenn man nicht gerade Firebug laufen hat… naja, ein Auskommentieren des Funktionsaufrufs von d() und endlich ist auch etwas das nach weiterem Quellcode aussieht zu erkennen.

Nuit du Hack 2013 - huge.js - firebug outputWiederholt man den ganzen Vorgang  und schneidet die 24,99999MB Hex nicht aus wird dieser Code erzeugt:

Nuit du Hack 2013 - huge.js - more obfuscated codeAuf den ersten Blick ein wenig enttäuschend, da es sich wieder um ganz viel hässlichen Hex-Krams handelt. Allerdings fällt auf, dass der Code sich verändert hat und nicht mehr die selbe Struktur wie vorher aufweist (hierbei handelte es sich um nen Packer, hab ich aber so nicht sofort erkannt …. )

Scrollt man wieder bis ans Ende, “dadaaaa”:

Nuit du Hack 2013 - huge.js - beautified javascript– endlich mal richtiger Code zu sehen! Wieder selbes Spielchen wie vorher, Dateianfang und Dateiende extrahieren, das ganze lesbar machen durch Einrückungen etc. Nach ner halben Ewigkeit kommt dann die huge_unpacked.js dabei raus, bestehend aus etlichen Funktionen mit ganz viel Cryptovodoo.

Interessant sind aber eigentlich nur die letzten Zeilen, die Ausgabe der Inputbox und die Validierung der Eingabe.

/* * Password checking routine * charset: 0-9a-zA-Z<>(){}-+ */ 
function unlock(node) { 
  var code = node.value; 
  if (code && (code.length == 5)) { 
    if ( (xxx(code).substr(0,16)=='b3336efd42e29780') && (xxx(kkk(code)).substr(16,16)=='261804c5f2f0a47e') ) { 
      var flag = document.createElement('span'); 
      var t = document.createTextNode('YAY, you got the flag ! --> '+xxx(code)); 
      flag.appendChild(t); 
      flag.style.font='Helvetica, 1.2em, bold'; 
      document.getElementById('panel').appendChild(flag); 
      node.style.display = 'none'; node.value = '';
    } 
  } 
} 
/* Create an input box */ 
var pwd = document.createElement('input'); 
pwd.setAttribute('type','text'); 
pwd.setAttribute('value','Enter the unlock code here ...'); 
document.getElementById('panel').appendChild(pwd); 
pwd.addEventListener('keyup',  function() {
  var t=pwd;
  unlock(t)
}, false);

Bei jedem Tastendruck wird die Funktion unlock() mit dem Inhalt der Inputbox aufgerufen, wenn der Inhalt die Länge 5 hat, dann wird  ein Hash aus dem Code mittels der Funktionen xxx und kkk erzeugt und wenn der mit dem hart-codierten Wert übereinstimmt, dann gib den Hash in dem DIV-Container aus, den man dann hoffentlich auf der Webseite eintragen kann …

Aus dem Kommentar geht der erlaubte Zeichensatz für den Code hervor : 

0-9a-zA-Z<>(){}-+

Bevor man jetzt sich großartig mit dem Hashalgorithmus beschäftigt, kurz mal nachrechnen:

 26+26+10+8 = 70 Zeichen ^5 Stellen = 1.680.700.000 Möglichkeiten

Folgerung: das dürfte schneller ge-BruteForced sein als alles andere und sogar mit JavaScript sollte das nicht zu lange dauern

Kurze Cracking-Routine dazu direkt in das Dokument rein (ctf.html) führt dann irgendwann nach gar nicht so langer Zeit zum gewünschten Ergebnis „code == i<C3Js“

Okay, ich geb zu: die Routine is shaise, aber ich war jung und brauchte das Geld …

Nuit du Hack 2013 - huge.js - javascript cracking

Besonderheit: Bei Firefox gab es Probleme mit der Skriptausführung, nur die JS-Engine  von Opera war in der Lage die Jquery-Get Requests abzusetzen, wärend der Cracker lief.

Die Sources gibts hier:  files

Leave a Reply

Your email address will not be published. Required fields are marked *