DoubleThink

Warning: Division by zero on line 2



Textová 3D CAPTCHA

7. června 2008

Klasické textové CAPTCHAs už jednoznačně přestaly plnit svůj účel. V tomto případě ne kvůli spamerům, ale kvůli komerčním OCR, které dosáhly bodu, kdy jsou schopny číst text líp než člověk. Protiopatření? Opustit oblast OCR. Udělat obrázek, který čtečky nemají důvod umět číst.

Jako typický příklad zoufalství jmenujme Rapidshare.

Rapidshare CAPTCHA

Roztomilé.
Věřte nebo ne, baterie programů Symseek (odstraňuje zvlnění), CAP (rozlišuje kočičky od pejsků) a komerční FineReader 8 (OCR) zde dosahuje ve čtení skoro stoprocentní úspěšnosti - výrazně vyšší, než jaké dosahují lidé.

Nejsofistikovanější článek řetězu, FineReader, je zároveň tím nejslabším. Jediným, jehož vývoj nemají útočníci pod kontrolou.

Jak dál? Že pokračovat v linii deformování textu nemá cenu, už začínají provozovatelé chápat. Experimentuje se s fotkami nebo piktogramy, které nestačí jen přečíst, ale je potřeba je pochopit a pojmenovat.

To je ale cesta, která zvyšuje předpoklady ohledně intelektu návštěvníka. Je reálné očekávat, že návštěvník psaného webu umí číst. Je ale stejně reálné očekávat, že umí rozlišit kočku od aligátora? Nebo že ví, jak se řekne anglicky koule?

3D text

Faktu, že mozek je schopen snadno rozeznat prostorové objekty i ve značně neúplném dvojrozměrném průmětu, se dá využít právě proti robotům. Pokud nakreslíme text jako neúplný reliéf, půjde stále velmi snadno přečíst, ale OCR čtečky si s ním neporadí.

CAPTCHA
Zobrazit 3D text:


Generování 3D reliéfu v PHP

Vygenerování takového obrázku nemusí být nikterak složité. Jediné co potřebujeme, je vzorec pro projekci 3D prostoru do 2D plochy. V našem případě je to lineární perspektiva, kterou jsem vzal z minulého článku o perspektivě ve Flashi.

Jako matrici si předgenerujeme klasický obrázek s textem:

Matrice

Ve 3D zobrazení pak bude každý bod reprezentovat jeden pixel z matrice. Výška reliéfu pak bude určena světlostí barvy pixelu.

 
# inicializace
require './func/imagelightnessat.func.php';
require './class/linear_perspective.class.php';
$perspective = new linear_perspective();
 
 
# konfigurace rozměrů a pozic
$matrix_dim = array('x' => 80, 'y' => 30);
$captcha_dim = array('x' => 450, 'y' => 120);
$distance = array('x' => 1, 'y' => 1, 'z' => 1);
$metric = array('x' => 10, 'y' => 20, 'z' => 5);
$offset = array('x' => 0, 'y' => -60);
 
# matrice
$matrix = imagecreatetruecolor($matrix_dim['x'], $matrix_dim['y']);
$black = imagecolorexact($matrix, 0, 0, 0);
$white = imagecolorexact($matrix, 255, 255, 255);
imagefill($matrix, 0, 0, $white);
 
# font calibri neni kvůli licenčním podmínkám připojen, použijte jakýkoliv svůj
imagefttext($matrix, 20, 0, 2, 25, $black, './resources/calibri.ttf', 'ABCDE');
 
# výpočet bodů ve 3d
$point = array();
for ($x = 0; $x < $matrix_dim['x']; $x++) {
	for ($y = 0; $y < $matrix_dim['y']; $y++) {
		$lightness = imagelightnessat($matrix, $x, $y);
		$point[$x][$y] = $perspective->get_projection(array('x' => $x * $metric['x'] + $distance['x'], 'y' => $lightness * $metric['y'] + $distance['y'], 'z' => ($matrix_dim['y'] - $y) * $metric['z'] + $distance['z']));
	}
}
imagedestroy($matrix);
 

Zde je tedy vytvořen obrázek s černým textem ABCD na bílém pozadí. Poté je zjištěn jas každého pixelu (zjednodušeným výpočtem L složky z RGB barev pixelu, zjištěným funkcí imagecolorat()).

Projekce je situována tak, aby obrázek ležel na ploše „xz“ a složka jasu stoupala v ose „y“. Kladné vektory os chápané GD funkcemi se liší od obecného matematického modelu, takže například souřadnice „z“ odpovídá převrácené hodnotě pozice pixelu v ose „y“.

Nakonec jsou určeny pozice všech bodů v projekci lineární perspektivy a zapsány do pole. Všimněte si, že vstupní prostorové souřadnice jsou ještě upravovány vektorem vzdálenosti od počátku ($distance) a násobeny metrikou ($metric). Takto pak lze měnit pozice a rozměry výsledného objektu.

Postupme dále.

 
# obrázek captcha
$captcha = imagecreatetruecolor($captcha_dim['x'], $captcha_dim['y']);
 
# antialiasing čar - pro menší zátěž lze vypnout
imageantialias($captcha, true);
 
$black = imagecolorexact($captcha, 0, 0, 0);
$white = imagecolorexact($captcha, 255, 255, 255);
imagefill($captcha, 0, 0, $white);
 
# vykreslení vrstevnic
for ($x = 1; $x < $matrix_dim['x']; $x++) {
	for ($y = 1; $y < $matrix_dim['y']; $y++) {
		imageline($captcha, -$point[$x - 1][$y - 1]['x'] + $offset['x'], -$point[$x - 1][$y - 1]['y'] + $offset['y'], -$point[$x][$y]['x'] + $offset['x'], -$point[$x][$y]['y'] + $offset['y'], $black);
	}
}
 
# výstup
header('Content-type: image/png');
imagepng($captcha); 
 

Tohle už je hračka. Je vytvořen finální obrázek a mezi jednotlivými diagonálně sousedícími body jsou nakresleny úsečky pomocí funkce imageline().

Povšimněte si ještě funkce imageantialias(). Tuto je možné nepoužít a čáry pak nebudou vyhlazeny, což sníží datovou velikost obrázku i výpočetní nároky na jeho sestavení.

3dcaptcha.zipZIP (3 kiB)

Implementace

Ukázkový obrázek je v té nejzákladnější formě. Reliéf je tvořen velkým množstvím bodů a je tak dost zřetelně čitelný. Pro výrazné zvýšení ochrany by určitě šlo zmenšit počet bodů, vybrat jiný font, přesunout kameru (viz třída linear_perspective) do ostřejšího úhlu, zvětšit metriku v ose „z“, nebo doplnit do matrice šum, který se pak projeví jako nerovnost plochy. Možností je mnoho.

Závěr

Řekl bych, že jako ochrana proti běžnému komentářovému spamu je (jakákoliv) obrázková CAPTCHA zbytečné obtěžování uživatelů. Na to zatím pořád bohatě stačí ochrany na bázi javascriptu. Ale na zabezpečení například autentizace nebo registrace, tedy tam, kde už reálně hrozí cílený útok, může být 3D text velmi účinný a minimálně obtěžující.

Na konec bych rád dodal, že ideu trojrozměrného textového reliéfu jsem rozhodně nevymyslel já. Nápad je to už poměrně starý. Viz třeba www.graphcomp.com/captcha/. Tento článek spíš přibližuje programovou realizaci.


Komentáře

Salko

Vážne fajn nápad, normálne uvažujem že tento 3D štýl zaradím do svojho kódu pri generovaní captcha obrázkov...
Nejaký odkaz našiel aj Google: http://code.google.com/p/3dcaptcha/
8. června 2008

starenka

Voní hezky....
9. června 2008

Keff

Moc dobrý nápad a mnohem lepší než kočičky na rapidsharu (ty dávám tak s 40% úspěšností:)).

Jen mě napadlo, že když se to nechá takhle, tak si v obrázku hackeři vyberou kombinace pixelů ve stylu "když jsou tyhle čtyři pixely bílé, je první písmeno určitě A", ale stačí zavést pár náhodných prvků, a bude to OK.

Co třeba změna polohy kamery, změna vzorkování (rozestupu čar), změna tahu třeba na přerušovanou čáru, nebo kreslit čárou kde jsou náhodně vynechané pixely... Ale tohle se pořeší někde v praktickém nasazení.

PS: máš super archiv, gratuluju k dalšímu dobrému nápadu :).
PPS: ty emailové adresy v komentářích by to chtělo nějak obfuskovat, aby to nevyzobávali spammeři...
9. června 2008

DoubleThink

Jak jsem psal, aktuální obrázek by dost možná šel úspěšně přerastrovat a prohnat OCR čtečkou. Takže by neškodilo zmenšit počet bodů a přidat šum do matrice. Písmena by taky třeba šla střídavě vynořit a zanořit (základní barva šedá, písmena náhodně černá a bílá).
Atd. atd. To je obrovská výhoda tohoto postupu - můžeš jednoduše vymyslet jakoukoliv úpravu.

E-mailové adresy jsou obfuskovány podle DGX: http://latrine.dgx.cz/experiment-s-maskovanim-e-mailu-pred-roboty
9. června 2008

Messa

Tímhle se problém neřeší - je otázka určitě jen pár hodin programování vytvořit filtr, který reliéf převede zpět do 2D podoby čitelný OCR. Přidávat nějaký šum, střídat barvy nebo vynořování vede opět k tomu, co je zmiňováno v prvním odstavci: člověk to už potom stěží přečte, počítač snadno. Já ten filtr teda vytvořit neumím, ale spoléhat se na to, že to vypadá hezky a že si někdo myslí, že by to mohlo fungovat, není správná cesta.

"Nemít důvod umět číst" by opravdu mohlo být dobrým řešením - koncipovat službu tak, aby z ní tito "útočníci" neměli prospěch. Takhle já chápu větu "nemít důvod umět přečíst", ne hledání dalších antiOCR patvarů :-)

Rozpoznávání textu a další úlohy patří do oblasti umělé inteligence (a dalších oblastí), a upřímně, nechci nikoho urážet, ale od programování v PHP k AI je dost dlouhá cesta...
10. června 2008

DoubleThink

Filtr, který z reliéfu v perspektivě, s náhodně zvolenou pozicí, rotací a ohniskovou vzdáleností kamery, ještě znečištěný šumem - vrátí zpátky matrici - za pár hodin? Trochu se prober.

"Nemít důvod umět číst" by opravdu mohlo být dobrým řešením - koncipovat službu tak, aby z ní tito "útočníci" neměli prospěch. Takhle já chápu větu "nemít důvod umět přečíst", ne hledání dalších antiOCR patvarů :-)

Napíšu ti tu větu sem znovu, Udělat obrázek, který čtečky nemají důvod umět číst. Tak.
Neočekává se, že by komerční OCR kdy v budoucnu uměly číst texty v prostoru. Není k tomu žádný důvod. Naopak uměle znečištěné a rozmazané 2d texty ano, protože v praxi je přesně tohle často potřeba (texty z faxů, kopírek a podobně).

Rozpoznávání textu a další úlohy patří do oblasti umělé inteligence (a dalších oblastí), a upřímně, nechci nikoho urážet, ale od programování v PHP k AI je dost dlouhá cesta

Já taky v PHP nepíšu rutinu na rozpoznávání textu. Kromě toho, prostředky na vývoj a provoz takových systémů nejsou zrovna zanedbatelné - proto spameři používají komerční řešení.

10. června 2008

Captcha shit

Občas něco podobného vygoogluju, ale teď mi to fakt nedá...

Jako grafický tutorial k PHP dobré. Nicméně podobné grafické "captcha" jsou pro megaloman-webmaster-kretény jako asi i ;) R. Hulán (a jeho paranoia-přichrochtávači)...

Ze stránek, na kterých musím luštit takovouhle grafickou s-r-a-č-k-u, rychle pryč... Proč prostě nestřídáte textové a hlavně čitelné otázky, např. "Kolik je 1 + 5" (uživatel by měl napsat 6), nebo "Jaký je dnes den?" (můžete dát na výběr např.: PO, ÚT, ST, ...). Když vidím ty divoké obrázky, kde není poznat co to je, navíc na debilních fórech o prdu, tak se mi fakt chce blít (dobrou chuť).
12. června 2008

DoubleThink

Kdyby sis přečetl poslední odstavec, zjistil bys, že souhlasím :\ (RH by pravděpodobně doplnil, že nejsi schopen porozumnět psanému textu).

Tohle je trochu jiný scope. CAPTCHA, jakou používá RS nebo třeba LiveID nemůže znít "kolik je 1+5". Můj návod je rovnocená a přitom mnohem míň nepříjemná alternativa k rozmatlaným textům se zvířátkama.
12. června 2008

Lukáš Rejnart

Myslím si, že problém oblafnutí robotů se rovná problému šifrování, při dnešním výpočetním výkonu počítačů běžně dostupných je jen otázkou minut nalezení správného postupu :(
15. června 2008

YoSarin

DOR (definitivní oblafnutí robotů ;) ) je věc přinejmenším nereálná (jak stejně asi všichni tuší). Každá antispamová ochrana se dá prolomit. Tím každopádně nechci říct, že by nemělo smysl proti tomu bojovat.

Já osobně vidím problém jinde - jakmile je obrázek "nerozlousknutelný" softwarem, odříznete od služby lidi odkázané na čtečky, tzn. slabozraké a slepé... Na druhou stranu - pokud by se tenhle druh captchy používal např. jen u registrace, tak by asi neměl být problém v poskytnutí ekvivalentní náhrady (registrace pomocí mailu nebo tak něco).
16. června 2008

Medvídek

Pokud Váš web bude pro někoho zajímavý, tak můžete střídat ochrany donekonečna a stejně Vám to bude k prdu :)
17. června 2008

Evilda

Je to pěkné, ale pro robota mnohem snažší na přečtení než kočičky a pejsci
27. ledna 2009

Matak

Na druhou stranu díky captcha se OCR postupy dotáhly do téměř dokonalosti a celkově to mělo přínos (technologie šla kupředu)! V případě takovýchto captcha se jistě posune opět jiná technologie dopředu. A myslím, že na nějaký rok by to opět vydrželo, implementace není tak složitá, takže proč ne. Myslím, že pořád lepší než ty kočičky.

Otázky apod. věci jsou fajn, ale problém je, že se opakují a pokud někdo bude dělat útok cíleně, tak toho bota na to připraví.
27. ledna 2009

Bilbo

"Neočekává se, že by komerční OCR kdy v budoucnu uměly číst texty v prostoru. Není k tomu žádný důvod. "

Ale je. Např. automatické rozpoznávání dopravních značek a ukazatelů. Automatická analýza textu na fotografiích pro jejich klasifikaci. Není to úplně běžné použití, a zatím je to dost těžký problém, ale časem bude nějaký algoritmus tohleto řešící vcelku dobře dostupný.
8. února 2009

yano

Jedna a jedna je... Odpovez slovem!
11. března 2009

yano

alebo napr:
Protoze jste zaskrtl policka
"jsem robot" a "jsem prase" vase registrace je neplatna!
11. března 2009

DoubleThink

Jedna a jedna je... Odpovez slovem!
Nezapomínejte, že se pořád bavíme o ochraně, která by měla obstát proti cílenému útoku.
12. března 2009

Jirka V

No jo ale jak to připojím do formuláře kde mám ochranu s čísly jako napiš číslici dvě
2. listopadu 2009

Přidat nový komentář

Jméno *

E-mail

HTML je ignorováno. Můžete ale použít formátování [b]tučně[/b], [i]kurzíva[/i] a [pre]zdrojový kód[/pre]. Adresy jsou převedeny na odkazy automaticky a mají atribut rel=nofollow.

Komentář *