Bypassing the random image anti-spam feature
January 12th, 2006 by Sid, Filed under: Spam, Web
A friend of mine has been playing a game which you play through the browser, some tasks can be automated which allows the player to earn money or increase stats quickly, or while not at the computer (this particular action does not interact with other players). My friend then create a bookmarklet (?) which would automate this task. All was hunky dory until the game asked the user to read an image and copy the text down. This is done precisely to prevent these automated bots, still…. it provides an interesting problem. How could you read the image and continue the game automatically?
I couldn’t sleep the first night I was presented with this problem, I went down more dead ends than I thought existed in this kind of a problem. Eventually I decided to take a break and start again. Logically how could JavaScript read an image? It can’t, it would need some other technologies, these would have to reside either on a remote domain if they are web based or on the local machine. JavaScript cannot run either of these, so it seemed I came to a dead end, again. In fact, it would be impossible to solve this using JS at all, you would infact need a seperate program precisely because you need to call either a remote web site or a local program. Realising this decreased my enthusiasm as now it was merely an experiment to see if it could be done.
I remembered a certain web service that I’d used a while back, namely WhatTheFont (WTF). This service can read an image and tries to deduce the font used from the characters it can find. I figured I could use this to read the characters in an image.
I found a random image such as which is the kind of image the user has to copy. I tried uploading the image to the WTF site, but it failed to read the image. I noticed the sample images they provide are much larger, so I scaled up my image and submitted it again, this time WTF could read the image perfectly.
Now… if only I could get some PHP code to read an image file, scale it up, submit it to WTF and read the response.
I should say that the code I provide is very untidy, this is because it’s the result of sleepless nights and at points I hacked certain bits, then edited them later again. I explain the code just below the code itself.
function doIt()
{
$r = rand(100000,999999);
if (@imagecreatefromgif($_GET['img']))
$ext = 'gif';
else
$ext = 'png';
if (!@copy ($_GET['img'],$r.$ext))
die("Error");
chmod($r.$ext,0777);
$img = up_size($r.$ext,5,$ext);
$lines = file("http://www.myfonts.com/WhatTheFont/Upload?url=http://www.whiteacid.org/img_reader/".$r.$ext);
parseInput($lines);
unlink($r.$ext);
}
The code initially determines what image type the image is. The script only allows PNG and GIF. BMP wouldn’t be used as no one really uses it any more and JPG wouldn’t be used as it would blur the lines making it difficult for humans to read the letters. It then saves the image to the same folder the script resides in under a random name (or quits if there’s a problem). I did this because for some reason the script seemed to work better when the image was in the same folder, or at least on the same domain. I then scale the image up (that function is below), perform the request and run parseInput (again, code coming below). Finally I remove the image (which up_size() creates).
The up_size function’s code is here:
function up_size($imageUrl,$ratio,$extension)
{
if ($extension == 'gif')
{
$src_img = imagecreatefromgif($imageUrl);
}
else
{
$src_img = @imagecreatefrompng($imageUrl);
}
$origw = imagesx($src_img);
$origh = imagesy($src_img);
$dst_img = imagecreatetruecolor($origw*$ratio,$origh*$ratio);
imagecopyresampled($dst_img,$src_img,0,0,0,0,$origw*$ratio,$origh*$ratio,imagesx($src_img),imagesy($src_img));
imagepng($dst_img, "$imageUrl");
//imagepng($dst_img);
return $dst_img;
}
It reads the file and creates an image object, reads it’s width and height, makes a new image with a larger canvas and copies the old smaller image onto this canvas streching it to fit. That’s how it scales up images. Finally it saves this in a file.
Now that the image had been scaled up it was sent off to WTF and the reponse was stored in a variable ready to be parsed. Now, before I give the code for the parsing section you should know how the outputted HTML looks. Very simply WTF prints out;
<input type=’text’ name=’ch[0]‘ id=’wtfchar0′ value=’T’ size=’2′ maxlength=’1′ style=’font-size:20; font-family:verdana; text-align:center;’>
<input type=’text’ name=’ch[1]‘ id=’wtfchar1′ value=’o’ size=’2′ maxlength=’1′ style=’font-size:20; font-family:verdana; text-align:center;’>
<input type=’text’ name=’ch[2]‘ id=’wtfchar2′ value=’k’ size=’2′ maxlength=’1′ style=’font-size:20; font-family:verdana; text-align:center;’>
<input type=’text’ name=’ch[3]‘ id=’wtfchar3′ value=’y’ size=’2′ maxlength=’1′ style=’font-size:20; font-family:verdana; text-align:center;’>
<input type=’text’ name=’ch[4]‘ id=’wtfchar4′ value=’o’ size=’2′ maxlength=’1′ style=’font-size:20; font-family:verdana; text-align:center;’>
There is more stuff and things in between those segments, but that’s what we’re after. The easiest thing to search for would be id=’wtfchar$n‘, then parse the value field after it. We’d have to note that if the character would not be identified the value attribute would be blank, so we could return a question mark instead, to let the user know that one character remained unknown. ok, the code
function parseInput($lines)
{
$c=0;
foreach ($lines as $line_num => $line)
{
if (strpos($line,"id='wtfchar$c'") != false)
{
$char = substr($line,strpos($line,"id='wtfchar$c' value='")+strlen("id='wtfchar$c' value='"),2);
if ($char == "' ")
$char = '?';
else
$char = substr($char,0,1);
echo $char;
$c++;
}
}
}
For each line of output search for “id=’wtfchar$c’” where $c is an incrementing integer which starts at 0. Essentially if found (then you’re on the right line of code), then parse out the value or echo a question mark.
One more line of code is also required, you need to run doIt(), then you’re done.
That’s about it, using that code you can parse text from an image. This allows you to complete some forms automatically. This obviously could be used for spamming reasons, which is why instead of using images like I’ve used them people should use ones like hotmail and gmail:

To see the script in action I’ve made one script which allows you to create images of text and the other one as described here. I used to host examples of this code in action but my new host doesn’t allow file-access from a URL.




Pingback: SecuriTeam Blogs » Defeating Voice Captchas