Montag, 1. Januar 2018

Pole pole!

An diesem Neujahrswochenende wollte ich nach den Teilerfolgen auch das ganze Rätsel lösen. Wenn man mit einem Buch, einer definierten Textstelle und einem Blatt voller Zahlen dasteht, dann kommt man mit ein wenig Recherche schnell auf die Vermutung, dass es sich um die Beale-Chiffre handelt.

Dahinter steckt eine abenteuerliche Geschichte von einem Schatz, den ein gewisser Thomas J. Beale in den Jahren 1820/22 versteckt haben soll. In insgesamt 3 verschlüsselten Botschaften hat er den Schatz und vermutlich seinen Lageort beschrieben. Von diesen 3 Botschaften konnte man bis heute nur die zweite entschlüsseln, wobei die Nummern in die Anfangsbuchstaben des soundsovielten Wortes der amerikanischen Unabhängigkeitserklärung übersetzt wurden. Niemand weiß bis heute, welchen Text man für die Entschlüsselung der anderen beiden Botschaften braucht. Deshalb weiß man bisher auch nur was in dem Schatz vergraben ist, aber nicht, wo der Schatz liegt!
Aufgrund der Vermutung einer Beale-Chiffre habe ich schnell den Anfang des Kapitels mit der Textstelle abgeschrieben. Mit ein wenig Excel konnte ich dann schnell einen Entschlüsselungsversuch nach Beale starten. Leider zunächst ohne Erfolg. Obwohl ich 6 Varianten probiert habe: Start bei der Überschrift oder beim Kapitelanfang oder bei der Textstelle und Trekking-Stöcke als ein oder zwei Worte.

Da ich mir eigentlich sicher war, dass es sich um eine Beale-Chiffre handelte, mailte ich mein Ergebnis noch kurz vor dem Aufbruch in den Silvesterurlaub an Kai. Er und Nathalie fragten sich, was schief gelaufen sei (sie hatten ihr Exemplar des Buches an mich verliehen). Kurz darauf fand ich den Fehler: Ich hatte ziemlich am Anfang des Kapitels einen Satz schlicht vergessen und dadurch hat sich alles verschoben. Ich erhielt jetzt folgenden Text:

LiebeRJAnwirwuenScHEnDiRallesGutEzumgeBUrTsTaGaUchwenneSJeTzTveRmUTLichschOnLangenacHTRaeGlicHistnUnhAstdüjaEinEnteiLdEsRaeTsElsschongeloestUnddAnnveRmUtlichauchdieHOmMAgeAnUnseREnToLLengemeiNSAMenkiLiManJaRouRlAubErkAnntferTiGbistduAllErDinGsnochnichtUNteRdeRUrlwwwPUnKthUfEnbacHPunktccSlAshJAnscachegEhteswEiterviELeRFolg

Einerseits freute ich mich, den dritten Teil auch gelöst zu haben. Andererseits wartete ein neues Rätsel auf mich unter www.hufenbach.cc/janscache. Als erstes wartete dort die folgende Frage auf mich:

"Wie lautete die Begründung für langsamen Seitenaufbau auf der Webseite der TK am 12. Dezember 1996?"

Wie sollte ich das am Wochenende beantworten, ohne an meinem Arbeitsplatz bei der TK zu recherchieren? Ja, ich erinnerte mich, dass wir im Dezember 1996 Antwortzeitprobleme in unserem System hatten und ich deshalb sogar Dörte und die Kinder beim Weihnachtsmärchen im Ohnsorgtheater versetzt hatte. Aber das war TKeasy, unser System für die Mitarbeiter, und nicht unser Internetauftritt.

Ich fragte mich dann, wo Kai und Nathalie die Antwort gefunden haben könnten. Sie waren damals ja vermutlich noch im Grundschulalter und hatten sicherlich noch nichts von der TK gehört. Dann fiel mir das Internet-Archiv ein. Dort werden regelmäßig viele Websites gesichert, damit sie der Nachwelt erhalten bleiben.
Ich fand dort auch den Snapshot einer Webseite der TK aus dem Dezember 1996 - noch unter der alten Adresse www.tk-online.de:
Als ich dort auf Hilfe und dann auf "World Wide Wait?" klickte, hatte ich meine Antwort. Als nächstes erwartete ich eine ähnlich Frage. Stattdessen erhielt ich die Aufforderung "Break the code!"

Ich fragte bei Kai an, ob ich wirklich den Code auf www.hufenbach.cc analysieren und brechen sollte und er antwortete, dass mir sein Webserver sonst wohl nicht das Lösungswort verraten würde. Inzwischen war es schon Samstagabend und ich schaffte es nur noch, ein paar Debug-Versuche zu machen aber keinen ernsthaften Angriff (für die Nicht-Techniker: Drückt mal F12 im Browser, wenn Ihr wissen wollt, was wirklich unter der Haube im Browser passiert!).

Ich war mit Dörte über das  Wochenende nach St. Michaelisdonn gefahren, damit sie bei etwas Nordseeluft endlich ihre Erkältung los wird. Der Ort war ein wenig trostlos, das Zimmer auch und draußen roch es nach Pferdemist. Das war trotzdem OK, denn wir sind Silvester nach Friedrichskoog und Büsum gefahren und ansonsten hat Dörte sich gesund geschlafen. Dadurch hatte ich am Silvesternachmittag und -abend viel Zeit, mir den Code anzusehen. Hier mal ein Ausschnitt:

var _0x84eb=['getElementById','innerHTML','wTRST','Ygu','solution','erJKn','round','gfYsO','random','length','value','KlVYM','rkFAr','substr','MaM','wAvic','CxQmG','ObZSk','bWkge','wGLSu','http://www.hufenbach.cc/janscache/php/submit.php','IkghT','?answer=','then','aBt','rWLGT','rETAz','json','OYj','qpr','LEzbU','yLngF','question'];(function(a,c){var b=function(b){while(--b){a['push'](a['shift']());}};b(++c);}(_0x84eb,0x76));var _0xb84e=function(a,c){a=a-0x0;var b=_0x84eb[a];return b;};function init(){var a={'wGLSu':function b(a){return a();}};a[_0xb84e('0x0')](loadData);}function loadData(c){var b={'IkghT':_0xb84e('0x1'),'ehLIq':function d(a,b){return a(b);}};let a=b[_0xb84e('0x2')];if(c){a=a+_0xb84e('0x3')+b['ehLIq'](encodeURI,c);}fetch(a)[_0xb84e('0x4')](function(b){var a={'rWLGT':function c(a,b){return a===b;},'pArZF':_0xb84e('0x5'),'rETAz':function d(a){return a();}};if(a[_0xb84e('0x6')]('wOv',a['pArZF'])){a[_0xb84e('0x7')](loadData);}else{return b[_0xb84e('0x8')]();}})

Man nennt das obfuskierten Code, also bewusst unleserlich gemachten Code. Damit will man verhindern, dass Leute, die den Programmcode ausführen können, ihn auch kopieren und modifizieren können. Zusätzlich gab es 2 Funktionen, die völlig abgefahrene Zeichenkombinationen wie diese enthielten:

var key = aesjs.util.convertStringToBytes((![]+[])[+!+[]]+[!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+([][[]]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+!+[]+!+[]+[+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(+![]+([]+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[]) ...

Diese Kombinationen aus den Zeichen ()[]+! waren seitenlang. Wenn ich runterscrollte, ergaben sich Effekte optischer Täuschung, denn es gab plötzlich Farbränder! Und das sollte ich alles verstehen?
Nein, das musste auch anders gehen!  Jetzt wollte ich Kai mit seinen eigenen Waffen schlagen!

Durch das Debuggen hatte ich schon herausgefunden, dass im Prinzip nur 2 Bytes, die sich aus der Antwort berechnen ließen, an den Server übertragen wurden. Das gab also nur 65536 Möglichkeiten, die konnte ich doch einfach durch ein Skript absetzen lassen und dann die Serverantworten auf meiner Festplatte speichern und durchsuchen. Ganz so leicht hat es mir Kai aber nicht gemacht: Die beiden Bytes waren mit viel Sicherheitsbrimborium aufgepeppt, damit der Webserver prüfen kann, ob hier jemand geschummelt hat. So ein Request sah ungefähr so aus:

answer=gxLx8rcl6l7lorNxVgVwyA==U1NVWQ==

Wenn man für dieselben 2 Bytes noch einmal den Server anfragte, dann sah der Request schon wieder anders aus, weil ein Zufallswert in die Berechnung einfloss. Ich habe nun die Berechnungsvorschrift für das Ermitteln der 2 Bytes aus der Antwort auf etwas ganz Einfaches geändert und dann einfach Kais Original-Sicherheitsbrimborium aufgerufen. Frei nach dem Motto: Ich versteh es nicht, aber Kai wird schon dafür gesorgt haben, dass der Server das als richtig anerkennt.  Jetzt konnte ich gezielt alle 65536 möglichen Requests erzeugen.

Der Rest war Fleißarbeit: Die Rechenpower meines Notebooks war nicht sehr groß, ich musste deshalb das Skript in 16 Blöcken zu je 4096 möglichen Eingaben erzeugen. Das bedeutete jeweils 3 Minuten Dödelarbeit und dann 15 Minuten Warten - perfekt für einen Silvesterabend mit kranker Frau im Bett, Picknick im Gästezimmer und Dinner for One, Charlie Chaplin und Ohnsorg im Fernseher. Es war ein spezielles Silvester, das wir nicht so schnell vergessen werden.

Um 1 Uhr früh war mein Skript erstellt und ich habe es gestartet, bevor ich mich schlafen legte. Gegen 7 Uhr am Neujahrsmorgen war es fertig und ich habe die 65536 Ergebnisdateien auf meiner 
Festplatte nach der Größe sortiert. Es gab genau 2 Dateien mit abweichender Größe: "Break the code!" und die Lösung!

So ganz eindeutig war die Lösung dann doch nicht: Zuerst habe ich ein Lösungswort mit 58959 Bytes Länge versucht. Ich hätte lieber gleich die einfache Variante mit einer Länge von 16 Bytes versuchen sollen ...

Das war bisher das komplexeste Rätsel, danke an Kai und Nathalie. Der Bezug zu unserem gemeinsamen Urlaub in Afrika hat mir sehr gefallen. Als Gruß sage ich nur 5895 x pole pole

Anmerkungen:
Dieser Eintrag wurde nacherfasst am 5.1.2018.
Bei dem gruseligen Code aus den Zeichen ()[]!+ handelt es sich um JSFuck, eine esoterische Programmiersprache, die gültiges Javascript ist!

Keine Kommentare:

Kommentar veröffentlichen