Hier die “erste” Challenge (Addition is Hard) des diesjährigen Plaid CTF. Wie der Name bereits andeutet, geht es um eine Rechnenaufgabe. Ziel ist es, den Term
0x0 +0x7068703f = ?
zu lösen.
Im Nachhinein ist diese Aufgabe wohl lächerlich einfach, dennoch hat sie mir anfangs etwas Kopfzerbrechen bereitet. Denn nachdem alle Versuche, die Rechnung in verdiedensten Zahlensystemen zu lösen, mit “wrong key” beantwortet wurden, schien eine weitergehende Betrachtung für erforderlich.
Bei dem Ansatz, die Ziffern nicht als Zahlen sondern als ASCII-Zeichen zu interpretieren, stellt sich heraus, dass die zweite Ziffernfolge lesbaren Zeichen entspricht. Mit 0x70 = “p”, 0x68 = “h” und 0x3f = “?” gelangt man zu folgender Darstellung:
NULL + php? = ?
Auch wenn dieses Ergebnis weder Sinn macht, noch der richtigen Lösung entspricht, scheint es doch einen Hinweis auf eine mögliche Herangehensweise zu beinhalten. Das “php?” kann einfach kein Zufall sein und sollte uns dazu bringen, die Rechnung mit PHP zu assoziieren.
Wird die Rechnung nun testweise in ein PHP-Skript geschrieben, zum Beispiel so:
<?php echo 0x0 +0x7068703f; ?>
und anschließend Ausgeführt, erhält man folgende Ausgabe:
rup0rt@lambda:~/addition_is_hard$ php addition.php 3771785342
Wird diese Zahl als Lösung eingegeben erhält man tatsächlich die Antwort “correct key”.
Das Ergebnis lautet also “3771785342“.
Dennoch stellt sich für mich die Frage, wie PHP zu diesem Ergebnis kommt und was hierbei anders gerechnet wird, als bei meinen bisherigen manuellen Lösungsansätzen. Dafür führen wir ein paar Testausgaben durch:
<?php echo 0x00+5; // 10 echo 0x0 -5; // -10 echo 0x0 +5; // 10 echo 0x0 +0x5; // 10 echo 0x00 + 5; // 5 echo 5 +0x0; // 5 echo 0x1 +5; // 6 ?>
PHP scheint bei einigen Additions-Schreibweisen, bei denen die Null hexadezimal vorangestellt wird, eine Art Linksshift bzw. Multiplikation mit Zwei durchzuführen. Woher dieses Verhalten stammt oder ob es sich um einen Bug handelt, konnte ich bisher nicht in Erfahrung bringen.
Das stellt jedoch die Erklärung des Ergebnisses dar, denn während 0x7068703f eigentlich dem Dezimalwert 1885892671 entspricht, liefert PHP durch die (ungewollte?) Multiplikation mit Zwei den Wert 3771785342.
Da haben die doch wunderbar eine Aufgabe mit diesem Fehler in der aktuellen Engine gestaltet:
http://bugs.php.net/bug.php?id=61095
Ist nun aber behoben und wird daher wohl in nicht mehr ganz so vielen CTFs vorkommen diese Aufgaben… (schade eigentlich).