Bei dieser Challenge (Grab Bag 300) wird uns nur eine IP-Adresse und ein Port genannt. Weitere Informationen, die uns auf eine Lösung hinweisen, erhalten wir nicht. Die erste Verbindung zu dem angegebenen System mit “netcat” liefert uns folgende Ausgabe:
Der Server stellt sich selbst als “ATM Skimmer” vor. Solche Geräte werden an Geldautomaten angebracht um die Magnetkarte sowie PIN von Kunden zu kopieren bzw. zu speichern um später damit selbst Geld von deren Konten abheben zu können.
Die Konsolenausgabe des Servers zeigt uns hier jeweils drei Felder mit Datum samt einer vom Benutzer eingegebenen PIN sowie ein viertes Feld, in dem wir scheinbar selbst eine PIN eingeben müssen um die Aufgabe zu erfüllen. Die Felder selbst bestehen wiederum jeweils aus vier Blöcken unterscheidlicher Farben mit je neun Ziffern.
Da ich mich selbst nicht mit Skimmern auskenne und erst recht keine Erfahrung beim Angriff gegen die PINs von Geldautomaten habe, bleibt mir nichts anderes übrig als in den Feldern irgendwie ein Muster zu erkennen. Versuche mit Rechenoperationen die PIN aus den Ziffern zu bilden oder auf eine Wiederholung der Felder nach mehreren Hundert Eingaben zu warten, blieben jedoch erfolglos.
Nach einigen Ausgaben weiterer Felder und der Vermutung, dass jede Farbe wohlmöglich einer Ziffer der PIN zugeordnet sein könnte, ist mir folgendes aufgefallen: Feste Positionen der Ziffern aller drei Felder entsprechen jeweils einer bestimmten Ziffer der PIN. Diese Grafik soll das verdeutlichen:
In diesem Fall wäre die PIN also 0 8 0 2 . Das Problem ist, dass der Server die Verbindung nach kurzer Zeit wieder trennt. Aber selbst wenn man sehr schnell beim Erkennen der Positionen ist, großes Glück hat und es tatsächlich schafft, die PIN korrekt einzugeben, erscheinen vier weitere Felder mit erneuter PIN-Abfrage auf dem selben Timer. Es wird also nichts anderes übrig bleiben als ein Skript zur Lösung der Challenge zu schreiben. Ich habe dazu Perl verwendet und diesen Code erstellt:
#!/usr/bin/perl -w # DC20 Quals 2012 - g300 getPIN-Script # by rup0rt use IO::Socket; # create socket $sock = new IO::Socket::INET ( PeerAddr => '140.197.217.85', PeerPort => '10435', Type => SOCK_STREAM, Proto => 'tcp') or die "Could not create socket: $!\n"; sleep(1); # send password print $sock "5fd78efc6620f6\n"; $part = 1; # field counter @field = (); # temp field array while ($line = <$sock>) { chop($line); print "-$line-\n"; # get one field line and push numbers into if ((length($line)>5) && ($line =~ m/ (\d) .* (\d) .* (\d) .* (\d) .* (\d) .* (\d)/)) { push @field, $1, $2, $3, $4, $5, $6; } # field is full? then associate field number if ($#field == 35) { if ($part == 1) { @field1 = @field; } if ($part == 2) { @field2 = @field; } if ($part == 3) { @field3 = @field; } # all four fields fetched? then begin calculation of PIN if ($part == 4) { @field4 = @field; print "CALCULATE!!\n"; # iterate by PIN pos for ($pos = 0; $pos <= 3; $pos++) { # iterate each field position for ($i = 0; $i<=35; $i++) { # check if each PIN at this position matches if ($pin1[$pos] == $field1[$i]) { if ($pin2[$pos] == $field2[$i]) { if ($pin3[$pos] == $field3[$i]) { # position matches! got correct pin number push @pin4, $field4[$i]; } } } } } # array to scalar and print answer to STDIN and server socket $pin4 = join(" ", @pin4); print "PIN IS $pin4\n"; print $sock "$pin4\n"; # reset counter and answer to be prepared for next PIN calculation $part = 1; @pin4 = (); } @field = (); } # get and save entered PIN if ($line =~ m/User entered:/) { substr($line, 0, index($line, ": ")+2) = ""; if ($part == 1) { @pin1 = split(" ", $line); } if ($part == 2) { @pin2 = split(" ", $line); } if ($part == 3) { @pin3 = split(" ", $line); } $part++; } } close($sock);
Hierbei wird jede der 36 Ziffern eines Feldes mit einer Ziffer der PIN verglichen, wenn die Ziffern überein stimmen und dies für alle drei Felder und alle drei PINs gilt, wurde eine korrekte Position identifiziert, aus der dann mit dem vierten Feld eine Ziffer der einzugebenden PIN ermittelt werden kann.
Führt man dieses Skript nun aus, so kann man beobachten, wie mehrere PIN-Abfragen erfolgreich gelöst werden und letztendlich dieses Ergebnis stehen bleibt:
Die korrekte Lösung lautet somit “9238740982570237012935.32“.