> 16) & 0xFF; $g = ($rgb >> 8) & 0xFF; $b = $rgb & 0xFF; do { $new_r = $r + $rand_func(0,$deviation); $new_g = $g + $rand_func(0,$deviation); $new_b = $b + $rand_func(0,$deviation); } while ($new_r<0 || $new_r>255 || $new_g<0 || $new_g>255 || $new_b<0 || $new_b>255); $temp_col = ImageColorAllocate($im3,$new_r,$new_g,$new_b); ImageSetPixel($im3,$x,$y,$temp_col); } } } // for debug: //sendImage($im3); ////////////////////////////////////////////////////// ////// Avoid Brute Force Attacks: ////////////////////////////////////////////////////// if(empty($_SESSION['freecap_attempts'])) { $_SESSION['freecap_attempts'] = 1; } else { $_SESSION['freecap_attempts']++; // if more than ($max_attempts) refreshes, block further refreshes // can be negated by connecting with new session id // could get round this by storing num attempts in database against IP // could get round that by connecting with different IP. // in short, there's little point trying to avoid brute forcing // the best way to protect against BF attacks is to store the dictionary in .htaccess'ed directory if($_SESSION['freecap_attempts']>$max_attempts) { $_SESSION['freecap_word_md5'] = false; $bg = ImageColorAllocate($im,0,0,0); ImageColorTransparent($im,$bg); $red = ImageColorAllocate($im, 255, 0, 0); ImageString($im,5,5,20,"service no longer available",$red); sendImage($im); } } ////////////////////////////////////////////////////// ////// Choose Word: ////////////////////////////////////////////////////// if($use_dict==1) { // load dictionary and choose random word // keep dictionary in non-web accessible folder, or htaccess it // or modify so word comes from a database; SELECT word FROM words ORDER BY $rand_func() LIMIT 1 // took 0.11 seconds when 'words' had 10,000 records $words = file($dict_location); $word = strtolower($words[$rand_func(0,sizeof($words)-1)]); // cut off line endings/other possible odd chars $word = ereg_replace("[^a-z]","",$word); // might be large file so forget it now unset($words); } else { // generate pseudo-random string // doesn't use ijtf as easily mistaken // I'm not using numbers because the custom font I created doesn't support anything other than // lowercase or space (but you can download a new font or create your own using my GD fontmaker script) $consonants = 'bcdghklmnpqrsvwxz'; $vowels = 'aeyuo'; $word = ""; $wordlen = $rand_func(5,6); for($i=0 ; $i<$wordlen ; $i++) { // don't allow to start with 'vowel' if($rand_func(0,4)>=2 && $i!=0) { $word .= $vowels{$rand_func(0,strlen($vowels)-1)}; } else { $word .= $consonants{$rand_func(0,strlen($consonants)-1)}; } } } // for debug //$word="qgfthn"; // save hash of word for comparison // using hash so that if there's an insecurity elsewhere (eg on the form processor), // an attacker could only get the hash // and although it's fairly trivial to brute force md5 hashes of short strings, // it adds an extra layer of protection. $_SESSION['freecap_word_md5'] = md5($word); $_SESSION['send_word'] = $word; ////////////////////////////////////////////////////// ////// Morph Image: ////////////////////////////////////////////////////// // write word in random starting X position $word_start_x = $rand_func(4,20); // y positions jiggled about later $word_start_y = 0; // could randomly choose between a few different fonts here. $font = ImageLoadFont($font_location); ImageString($im2, $font, $word_start_x, $word_start_y, $word, $text_colour2); // for debug: //sendImage($im2); // calculate how big the text is in pixels // (so we only morph what we need to) $word_pix_size = $word_start_x+(strlen($word)*$font_pixelwidth); // firstly move each character up or down a bit: for($i=$word_start_x ; $i<$word_pix_size ; $i+=$font_pixelwidth) { // move on Y axis $y_pos = $rand_func(-5,10); ImageCopy($im, $im2, $i, $y_pos, $i, 0, $font_pixelwidth, $height); // for debug: //ImageRectangle($im,$i,$y_pos,$i+$font_pixelwidth,50,$debug); } // for debug: //sendImage($im); // randomly morph each character on x-axis // massively improved since v1.2 // clear im2: ImageFilledRectangle($im2,0,0,$width,$height,$bg2); $y_chunk = 1; $morph_factor = 0; $morph_x = 0; for($j=0 ; $j