HTML-Captchas, besser als bei Slashdot

Auf Slashdot kam heute eine Meldung, dass die Zukunft des Captchas da ist! HTML-codierte Bilder (die Demo wurde wohl auf Grund des Slashdot-Effekts runtergenommen)!
Im Prinzip läuft der Vorgang ja recht simpel ab: Mit PHP sucht man jeden einzelnen Pixel des Bildes ab und schreibt dann die Farben als 1×1 Pixel große Elemente ins Markup hinein. So simpel das ist, desto grauslicher ist das Ergebnis. Ein 70×40 Pixel großes Bild ergibt mindestens 2800 Elemente. Ich habe mich diesem Code (siehe Link oben) etwas angenommen und einmal die Tabelle durch b-Elemente ersetzt und die width- und height-Eigenschaften per CSS im head-Bereich festgelegt. Das spart schon einmal einiges an Datenmenge ein (von ~ 120KB auf 90KB).
Natürlich gibt man sich damit nicht zufrieden. Das ganze lässt sich noch viel weiter optimieren: In den meisten Bildern (besonders Captchas) haben meist mehrere aneinander anliegende Pixel dieselbe Farbe. Das lässt sich ausnutzen, was mich zu diesem überarbeiteten Code führt:

  1. function image2Html_revised($strPathToImage) {
  2.     if(file_exists($strPathToImage)) {
  3.         $im = imagecreatefrompng($strPathToImage);
  4.         list($intWidth, $intHeight) = getimagesize($strPathToImage);
  5.         $html = '<div class="cap">';
  6.         for($y = 0; $y < $intHeight; $y++) {
  7.             $x = 0;
  8.             while($x < $intWidth) {
  9.                 $beginx = $x;
  10.                 $colors = imagecolorsforindex($im, imagecolorat($im, $x, $y));
  11.                 $color_old = sprintf('%02x%02x%02x', $colors['red'], $colors['green'], $colors['blue']);
  12.                 $color = $color_old;
  13.                 $x++;
  14.                 while($color == $color_old) {
  15.                     $colors = imagecolorsforindex($im, imagecolorat($im, $x, $y));
  16.                     $color = sprintf('%02x%02x%02x', $colors['red'], $colors['green'], $colors['blue']);
  17.                     $x++;
  18.                 }
  19.                 $x--;
  20.                 if($x - $beginx <= 1) {
  21.                     $html .= '<b style="background:#'. $color_old . ';">';
  22.                 } else {
  23.                     $html .= '<b style="background:#'. $color_old . '; width:' . ($x - $beginx) . 'px;"></b>';
  24.                 }
  25.             }
  26.             $html .= '<hr />';
  27.         }
  28.         $html .= '</div>';
  29.         return $html;
  30.     } else {
  31.         return 'Path to image was invalid!';
  32.     }
  33. }

Im Prinzip werden horizontal aneineander liegende, gleiche Pixel in ein Element zusammengefasst. Theoretisch könnte man auch vertikal arbeiten bzw. eine Weiche einbauen und dann die Methode verwenden, die für das betreffende Bild am geeignetsten ist.
Eine Demo gibt es hier.

13 Kommentare to “HTML-Captchas, besser als bei Slashdot”

  1.  Greg schrieb am 01. Jan 2007 um 19:18 zitieren

    Sehr nett :)

  2.  crash[kid] schrieb am 01. Jan 2007 um 19:56 zitieren

    Klingt alles schoen und gut, aber irgendwie habe ich den Eindruck, dass man da weit uebers Ziel hinausschießt. Ein Captcha soll doch nur dazu dienen den Menschen als solchen zu identifizieren. Warum man da anstatt einem Bild auf HTML-Code setzen sollte ist mir unklar. Ist es nicht viel einfacher ein Bild zu erstellen? Ich fuer meinen Teil denke halt immer nach dem Grundsatz „as easy as possible“ und damit bin ich bisher immer ganz gut gefahren ;)

    Ansonsten kann ich mich nur Greg anschließen. Wirklich gut durchdacht.

  3.  Mike® schrieb am 01. Jan 2007 um 20:12 zitieren

    Niedlich, (die demo hier) läuft allerdings nur in redlichen Browsern, der IE (jaja, wer sonst) ist nicht zu bewegen, die Abstände der Clear-HRs auf Null zu setzen.

  4.  Greg schrieb am 01. Jan 2007 um 20:24 zitieren

    Da hast du zwar Recht, crashkid, aber diese Bilder werden halt immer öfter „gehackt“. Und dann ist der Schutz halt wirkungslos. Und bevor da sowas bei rauskommt, ist es sinnvoller, das in HTML umzusetzen!

  5.  stephantom schrieb am 01. Jan 2007 um 23:07 zitieren

    Ich hatte vergessen zu erwähnen, dass das Prinzip rückwärts auch funktioniert. Man kann den generierten Code nehmen und wieder zu einem Bild zusammensetzen. Ist halt die Frage, ob das jemand tut.

  6.  Greg schrieb am 01. Jan 2007 um 23:31 zitieren

    Ist halt die Frage, ob das jemand tut.

    Ist ja eigentlich nur ne Frage der Verbreitung der Technik. Je mehr Sites das einsetzen, desto wahrscheinlicher wird auch das Ding umgangen werden. Aber je vielfältiger die Techniken sind, desto besser die Wirksamkeit, imo.

  7.  crash[kid] schrieb am 01. Jan 2007 um 23:53 zitieren

    Ich gebe dir Recht, Greg, dass man alles ein [ironie]klitzeklein wenig[/ironie] uebertreiben kann. Wenn man irgendwann mal Bilder-Captchas hat, die nicht mal mehr ein Mensch lesen kann, dann schrammt man natuerlich auch ordentlich am Ziel vorbei. Nichts desto trotz haben meiner Meinung nach bisher einigermaßen ordentlich entzifferbare Bilder durchwegs gelangt.
    Fuer mich ist die Methode oben nur eine Spielerei fuer alle xhtml-Freaks. Womit wir bei der Frage waeren: sind wir nicht alle ein bisschen xhtml-Freak? *g*

  8.  Greg schrieb am 02. Jan 2007 um 0:07 zitieren

    Nichts desto trotz haben meiner Meinung nach bisher einigermaßen ordentlich entzifferbare Bilder durchwegs gelangt.

    Naja, wenn das gereicht hätte, hätte Rapidshare ja nicht „aufgerüstet“. Das wurde wohl ausgehebelt.

  9.  Mike® schrieb am 02. Jan 2007 um 0:46 zitieren

    dass das Prinzip rückwärts auch funktioniert.

    Ist halt die Frage, ob das jemand tut.

    Natürlich tut das jemand;
    vorausgesetzt, dass sich das System aus den bekannten Gründen durchsetzt, bei grossflächiger Verbreitung von HTML-Captchas müssen sich die Spammer wieder was neues ausdenken. Und wenn es von der Rechenleistung schneller geht, als maschinell aus ’nem Screenshot einer Seite die Captcha-Grafik zu extrahieren und zu erkennen, dann wird das so gemacht.

    Der nächste Schritt im Spammer-kampf wäre dann eine Modifizierung des Scripts dahingehend, dass die HTML-Elemente zufällig gewählt werden, der wiederum nächste dann eine Mischung aus HTML+Grafiken,
    ich möchte gar nicht drüber nachdenken ;)

  10.  Maxx schrieb am 02. Jan 2007 um 22:11 zitieren

    Also ich fand die Idee bei http://undeadly.org ganz intressant, die CAPTCHA-Codes als ASCII-Bilder darzustellen.

  11.  Greg schrieb am 03. Jan 2007 um 13:37 zitieren

    Auch ne interessante Idee. Ohne da Experte zu sein, würde ich aber sagen, dass das relativ leicht zu knacken sein dürfte…

  12.  Mike® schrieb am 03. Jan 2007 um 19:49 zitieren

    „Relativ leicht“ heisst, dass die Seite gerendert werden muss und als Grafik ausgelesen. Momentan ist das imho heftiger Aufwand, aber leichter als eine „richtige“ Grafik im HTML-Captcha.

  13.  Akita schrieb am 02. Mrz 2008 um 23:36 zitieren

    Auch ein Jahr später würd ich noch mit diesem Code (und anderen Tricks, wie durch CSS nicht sichtbaren Formfeldern als Honeypots, Zeitstempeln usw.) arbeiten. Danke dafür.

    Dass der IE auch in der aktuellen 7.0.6000.16609 die hr falsch darstellt, lässt sich ja leicht umgehen – beispielsweise durch ein br, das per CSS mit {clear:both;} gestylt wird.

Trackback-Adresse | RSS-Feed für die Kommentare abonnieren

Hinterlasse einen Kommentar:


(Wir behalten uns vor Kommentare von dummen Menschen entweder zu löschen oder exemplarisch für die Nachwelt zu konservieren. Dumme Kommentare mit Werbelinks müssen leider auf zweiteres Privileg verzichten.)

XHTML: Du kannst diese Tags verwenden:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>