Simple Captcha Script

Small, short code snippets that other people may find useful. Do you have a good regex that you would like to share? Share it! Even better, the code can be commented on, and improved.

Moderator: General Moderators

Post Reply
AGISB
Forum Contributor
Posts: 422
Joined: Fri Jul 09, 2004 1:23 am

Simple Captcha Script

Post by AGISB »

I wrote a captcha script to verify user against machine on form input. Its not foolproof as more sophisticated ones were already broken by machines.

However for normal applications or forums this might be working.

I tried to put notes into the script.

Basic GD support is required

index.php

Code: Select all

<?php
session_start();
$TempString=\&quote;\&quote;;
// Now we generate a string that consists of 6 characters that are
// generated randomly. I choose 6, because I didn´t want the user to
// type forever. Of course, any other number would do as well.
//  (YOU USE ANOTHER NUMBER, YOU ALSO HAVE TO EDIT showimg.php) 
for ($i = 1; $i <= 6; $i++) {
	$TempString .= GetRandomChar();
}
//Now we create a Md5 string of that 
$_SESSIONї'Rand_Text'] = $TempString;
$image_md5 = md5($TempString.\&quote;secretpassphrase\&quote;);
$imagerand = mt_rand(1,9999999);
function GetRandomChar() {
	// This function generates our random chars
	mt_srand((double)microtime()*1000000);
	// Create a random number between 1 and 3
	$RandVal = mt_rand(1,3);
	// If the random number was 1, we generate a lowercase
	// character, if it was 2, we generate a number and if
	// it was 3, we generate an uppercase character.
	switch ($RandVal) {
		case 1:
	  	  // 97 to 122 are the ASCII codes for lower-case characters from a to z.
			$RandVal = mt_rand(97, 122); 
			// exclude lowercase L and O
			While ($RandVal == 108 || $RandVal == 111 ) {
				$RandVal = mt_rand(97, 122); 
			}
	  		break;
		case 2:
		  // 48 to 57 are the ASCII codes for the numbers from 1 to 9.
			$RandVal = mt_rand(49, 57);
			break;
		case 3:
	  		  // 65 to 90 are the ASCII codes for upper-case characters from a to z.
			$RandVal = mt_rand(65, 90);
			// exclude upperercase i and o 
			While ($RandVal == 73 || $RandVal == 79) {
				$RandVal = mt_rand(65, 90); 
			}
			break;
	}
	// Now we return the character, generated from the ASCII code
	return chr($RandVal);
}
?>
<html>
<head>
<META HTTP-EQUIV=\&quote;CACHE-CONTROL\&quote; CONTENT=\&quote;NO-CACHE\&quote;>
<META HTTP-EQUIV=\&quote;PRAGMA\&quote; CONTENT=\&quote;NO-CACHE\&quote;>
<META HTTP-EQUIV=\&quote;EXPIRES\&quote; CONTENT=\&quote;0\&quote;>
</head>
<table width=\&quote;500\&quote; border=\&quote;0\&quote; cellspacing=\&quote;0\&quote; cellpadding=\&quote;0\&quote;>
	<tr>
		<td><hr size=\&quote;1\&quote; noshade=\&quote;noshade\&quote;>
			<p><font size=\&quote;2\&quote; face=\&quote;Verdana, Arial, Helvetica, sans-serif\&quote;>Please type the code you see in the image into the textfield below. If you cannot  read the code, just press \&quote;<strong>Reload</strong>\&quote; to generate  a new one.</font></p>
			<p align=\&quote;center\&quote;><font size=\&quote;2\&quote; face=\&quote;Verdana, Arial, Helvetica, sans-serif\&quote;><img src=\&quote;showimg.php?<?php echo $imagerand.\&quote;&\&quote;.SID ?>\&quote; width=150 height=40></font></p>
			<form action=\&quote;verify.php\&quote; method=\&quote;POST\&quote; name=\&quote;ImgVerify\&quote;>
				<p> <font size=\&quote;2\&quote; face=\&quote;Verdana, Arial, Helvetica, sans-serif\&quote;>Enter the code here: </font> 
				<input name=\&quote;passcode\&quote; type=\&quote;text\&quote; size=\&quote;30\&quote;maxlength=\&quote;6\&quote; value=\&quote;\&quote;></p>
				<input type=\&quote;hidden\&quote; name=\&quote;hash\&quote; value=\&quote;<?php echo $image_md5 ?>\&quote;>
				<p> <input type=\&quote;submit\&quote; name=\&quote;Submit\&quote; value=\&quote;OK\&quote; />
				</p>
			</form>
			<p align=\&quote;center\&quote;><font size=\&quote;2\&quote; face=\&quote;Verdana, Arial, Helvetica, sans-serif\&quote;>
				<B>Note:</b> The code you enter is case sensitive!
			</p>
		</td>
	</tr>
</table>
</html>
img script showimg.php

Code: Select all

<?php
session_start();
// Create the image with width=150 and height=40
$the_image = imagecreate(150,40);
// Allocate two colors (Black & White)
// This uses the RGB names of the colors
$color_back = imagecolorallocate ($the_image, 175,175,175);
$color_lineї1] = imagecolorallocate ($the_image, 137,137,137);
$color_frontї1] = imagecolorallocate ($the_image, 67,67,67);
$color_frontї2] = imagecolorallocate ($the_image, 77,77,77);
$color_frontї3] = imagecolorallocate ($the_image, 97,97,97);
$color_frontї4] = imagecolorallocate ($the_image, 87,87,87);
$color_frontї5] = imagecolorallocate ($the_image, 87,87,87);
// Flood Fill our image with backcolor
imagefill($the_image, 0, 0, $color_back);
//We get the random text that was stored in our session var on the first page.
$RandomText = $_SESSIONї\&quote;Rand_Text\&quote;];
$_SESSIONї\&quote;Rand_Text\&quote;] = \&quote;\&quote;;
// here we create a couple of random lines to distort the background
for ($i; $i < 8; $i++) {
	ImageLine($the_image, mt_rand(0,25),mt_rand(0,40),mt_rand(125,150),mt_rand(0,40), $color_lineї1]);
}
// we now write the 6 random chars in our picture. Add a line if you chose another number in the initial page
mt_srand((double)microtime()*1000000);
imagechar($the_image, mt_rand(3,5), mt_rand(5,20),  mt_rand(5,20), $RandomTextї0] ,$color_frontїmt_rand(1,5)]);
imagechar($the_image, mt_rand(3,5), mt_rand(30,40),  mt_rand(5,20), $RandomTextї1] ,$color_frontїmt_rand(1,5)]);
imagechar($the_image, mt_rand(3,5), mt_rand(50,65),  mt_rand(5,20), $RandomTextї2] ,$color_frontїmt_rand(1,5)]);
imagechar($the_image, mt_rand(3,5), mt_rand(75,90),  mt_rand(5,20), $RandomTextї3] ,$color_frontїmt_rand(1,5)]);
imagechar($the_image, mt_rand(3,5), mt_rand(100,110),  mt_rand(5,20), $RandomTextї4] ,$color_frontїmt_rand(1,5)]);
imagechar($the_image, mt_rand(3,5), mt_rand(120,135),  mt_rand(5,20), $RandomTextї5] ,$color_frontїmt_rand(1,5)]);
//Now we send the picture to the Browser
header(\&quote;Content-type: image/png\&quote;);
imagepng($the_image);
?>
and the verify.php

Code: Select all

<?php
$passcode = md5($_POSTї'passcode'].\&quote;secretpassphrase\&quote;);
$controlhash = $_POSTї'hash'];
// Now we check, if the two strings are the same
if ($passcode == $controlhash) {
		echo \&quote;Well, thank you. You have entered the code correctly. <a href=index.php>Try again?</a>\&quote;;
	} else {
		echo \&quote;You haven´t entered the correct code. Please <a href=index.php>try again</a>!\&quote;;
	}
?>
The appearance of the pic can be set in showimg.php by adding colors etc.

d11wtq |

Code: Select all

tags used in this instance due to a bug with the

Code: Select all

tags and backslashes[/size][/color]
Last edited by AGISB on Sat Jan 22, 2005 3:38 am, edited 5 times in total.
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Post by onion2k »

Just a thought, and it'll affect any site that uses this image method for security, but this will won't meet accessibility guidelines and would render your site "illegal" under the UKs Disability Discrimination Act..
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Post by onion2k »

AGISB wrote:Well security wise I rather keep blind people from accessing the site then having spambots trash my forums.

Does the UK really have a law making websites illegal?

How about I put my site up in German. Is this illegal as well as someone who could not speak German form accessing the site?

Speak about weird laws.
Websites are perfectly legal. What is illegal* is offering a service to the public but not taking reasonable measures to allow disabled people to access it. Its the digital equivalent of opening a restaurant and having to put in a ramp to allow wheelchairs. And don't go thinking its a UK specific thing.. every country in the EU, and the USA, Canada, Australia, and lots of other countries either have it, or is in the process of bringing laws to do it in to power.

2005 is going to be the year of website accessibility.

* Not been tested in a court yet.


feyd v3 | this thread has been split to here
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

What you could do is, instead, do a "dumb" test by creating a mathematical equation that the user would have to solve in order to send the validation email.

I think I've seen a perl application of this idea: aha. Here it is: http://www.fourmilab.ch/webtools/feedbackform/

Very cool idea.
sam79
Forum Newbie
Posts: 2
Joined: Sat Jun 11, 2005 2:42 am

Post by sam79 »

hi
thanks for your useful security image code.
I used it and it run on my server but when I run it on the main server it didn't show the security image!
what's its problem?
I checked the main server and it's gd.dll was active,I really can't understand what the problem is.
please help me :cry: (as soon as possible)
thanks
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Post by John Cartwright »

Might want to fix your code

things like

Code: Select all

$RandomText = $_SESSION["Rand_Text"];
$_SESSION[\"Rand_Text\"] = \"\";
should be

Code: Select all

$RandomText = $_SESSION["Rand_Text"];
$_SESSION["Rand_Text"] = "";
sam79
Forum Newbie
Posts: 2
Joined: Sat Jun 11, 2005 2:42 am

Post by sam79 »

thanks Jcart
I did this change befor but it didn't work.
I think the diffrences between php versions make this problem, because my php version is 4.2.3 and main server's php version is 4.3.4
what a strange problem! usually the higher versions support lower versions , but it seems that php don't do it
Now how can I change the code to run on the main server?
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

sam79 wrote:thanks Jcart
I did this change befor but it didn't work.
I think the diffrences between php versions make this problem, because my php version is 4.2.3 and main server's php version is 4.3.4
what a strange problem! usually the higher versions support lower versions , but it seems that php don't do it
Now how can I change the code to run on the main server?
Like JCart said, you're escaping quotes for no apparent reason (PHP is seeing them as constants no doubt). It's not a version issue, it's more likely a php.ini issue.

If you're building an empty string then

Code: Select all

$var = "";

//or if you're wanting two qoutes as a string
$var = '""';
//or 
$var = """"; //Less readable than above
EDIT | Apologies sam that was aimed at the author :P Didn't read the post correctly. Same applies anyway (the code is flawed).
theda
Forum Contributor
Posts: 332
Joined: Sat Feb 19, 2005 8:35 am
Location: USA

Post by theda »

And by the way. The UK can't do <span style='color:blue' title='I&#39;m naughty, are you naughty?'>smurf</span> about non UK domain websites... It's not like they can arrest an Afghan for having a website that disabled people can't view ;)
Roja
Tutorials Group
Posts: 2692
Joined: Sun Jan 04, 2004 10:30 pm

Post by Roja »

theda wrote:And by the way. The UK can't do <span style='color:blue' title='naughty'>smurf</span> about non UK domain websites... It's not like they can arrest an Afghan for having a website that disabled people can't view ;)
If you read the whole comment, its not just the UK that has those rules. There are also accesibility requirements in the US, Canada, Mexico, and many EU countries.

But who cares what the *law* requires, what legitimate excuse can you give for shutting users out of your site because you choose not to allow them access?

There is no justification that is sufficient for "I offer a public service, EXCEPT for [insert minority here]". Its wrong, its illegal, and its just <span style='color:blue' title='I'm naughty, are you naughty?'>smurf</span>-poor programming.

Notably, you *can* use captcha's and be accessible - by offering an alternative that doesnt require visual confirmation. For example, a wav file that plays the answer.
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

Of course, that's even harder to program. ;-)
Roja
Tutorials Group
Posts: 2692
Joined: Sun Jan 04, 2004 10:30 pm

Post by Roja »

Ambush Commander wrote:Of course, that's even harder to program. ;-)
Nah, just pre-generate the wav files, and then just offer an array element randomly.

Really not that bad.
Post Reply