Ravens PHP Scripts: Forums
 

 

View next topic
View previous topic
Post new topic   Reply to topic    Ravens PHP Scripts And Web Hosting Forum Index -> Captcha Security
Author Message
NoFantasy
Worker
Worker


Joined: Apr 26, 2005
Posts: 114

PostPosted: Fri Nov 24, 2006 7:00 am Reply with quote

I made this quite simple, but working, captcha for BBtoNuke which hopefully should prevent many of the bot spammers from posting new topics and replies as guests. Logged in users is not affected.

In modules/Forums/posting.php
Find
Code:
include("includes/functions_post.php");

After, add
Code:
// MOD Captcha start

mt_srand ((double)microtime()*1000000);
$maxran = 1000000;
$captcha_num = mt_rand(0, $maxran);
// MOD Captcha end

Find
Code:
        switch ( $mode )

        {
                case 'editpost':
                case 'newtopic':
                case 'reply':
                        $username = ( !empty($HTTP_POST_VARS['username']) ) ? $HTTP_POST_VARS['username'] : '';
                        $subject = ( !empty($HTTP_POST_VARS['subject']) ) ? trim($HTTP_POST_VARS['subject']) : '';
                        $message = ( !empty($HTTP_POST_VARS['message']) ) ? $HTTP_POST_VARS['message'] : '';
                        $poll_title = ( isset($HTTP_POST_VARS['poll_title']) && $is_auth['auth_pollcreate'] ) ? $HTTP_POST_VARS['poll_title'] : '';
                        $poll_options = ( isset($HTTP_POST_VARS['poll_option_text']) && $is_auth['auth_pollcreate'] ) ? $HTTP_POST_VARS['poll_option_text'] : '';
                        $poll_length = ( isset($HTTP_POST_VARS['poll_length']) && $is_auth['auth_pollcreate'] ) ? $HTTP_POST_VARS['poll_length'] : '';
                        $bbcode_uid = '';

                        prepare_post($mode, $post_data, $bbcode_on, $html_on, $smilies_on, $error_msg, $username, $bbcode_uid, $subject, $message, $poll_title, $poll_options, $poll_length);

Change to
Code:
        switch ( $mode )

        {
                case 'editpost':
                case 'newtopic':
                case 'reply':
                        $username = ( !empty($HTTP_POST_VARS['username']) ) ? $HTTP_POST_VARS['username'] : '';
                        $subject = ( !empty($HTTP_POST_VARS['subject']) ) ? trim($HTTP_POST_VARS['subject']) : '';
                        $message = ( !empty($HTTP_POST_VARS['message']) ) ? $HTTP_POST_VARS['message'] : '';
                        $poll_title = ( isset($HTTP_POST_VARS['poll_title']) && $is_auth['auth_pollcreate'] ) ? $HTTP_POST_VARS['poll_title'] : '';
                        $poll_options = ( isset($HTTP_POST_VARS['poll_option_text']) && $is_auth['auth_pollcreate'] ) ? $HTTP_POST_VARS['poll_option_text'] : '';
                        $poll_length = ( isset($HTTP_POST_VARS['poll_length']) && $is_auth['auth_pollcreate'] ) ? $HTTP_POST_VARS['poll_length'] : '';
// MOD Captcha
                  if ( !$userdata['session_logged_in'] ) {
                  $captcha_check = ($HTTP_POST_VARS['captcha_check'] ) ? $HTTP_POST_VARS['captcha_check'] : '';
                  }
// MOD Captcha
                        $bbcode_uid = '';

                        prepare_post($mode, $post_data, $bbcode_on, $html_on, $smilies_on, $error_msg, $username, $bbcode_uid, $subject, $message, $poll_title, $poll_options, $poll_length, $captcha_check);

Find
Code:
switch( $mode )

{
        case 'newtopic':
                $page_title = $lang['Post_a_new_topic'];
                $hidden_form_fields .= '<input type="hidden" name="' . POST_FORUM_URL . '" value="' . $forum_id . '" />';
                break;

        case 'reply':
                $page_title = $lang['Post_a_reply'];
                $hidden_form_fields .= '<input type="hidden" name="' . POST_TOPIC_URL . '" value="' . $topic_id . '" />';
                break;

        case 'editpost':
                $page_title = $lang['Edit_Post'];
                $hidden_form_fields .= '<input type="hidden" name="' . POST_POST_URL . '" value="' . $post_id . '" />';
                break;
}

// Generate smilies listing for page output]

Change to:
Code:
switch( $mode )

{
        case 'newtopic':
                $page_title = $lang['Post_a_new_topic'];
                $hidden_form_fields .= '<input type="hidden" name="' . POST_FORUM_URL . '" value="' . $forum_id . '" />';
// MOD Captcha start
            if ( !$userdata['session_logged_in'] )
            {
            $hidden_form_fields .= '<img src="modules.php?gfx=gfx&amp;random_num=' . $captcha_num . '" border="1" alt="Securitycode" title="Securitycode" /><br>
            Type securitycode:<br>
            <input type="text" name="captcha_check" size="7" maxlenght="6" />
            <input type="hidden" name="captcha_num" value="' . $captcha_num . '" /><br>';
            }
// MOD Captcha end
                break;

        case 'reply':
                $page_title = $lang['Post_a_reply'];
                $hidden_form_fields .= '<input type="hidden" name="' . POST_TOPIC_URL . '" value="' . $topic_id . '" />';
// MOD Captcha start
            if ( !$userdata['session_logged_in'] )
            {
            $hidden_form_fields .= '<img src="modules.php?gfx=gfx&amp;random_num=' . $captcha_num . '" border="1" alt="Securitycode" title="Securitycode" /><br>
            Type securitycode:<br>
            <input type="text" name="captcha_check" size="7" maxlenght="6" />
            <input type="hidden" name="captcha_num" value="' . $captcha_num . '" /><br>';
            }
// MOD Captcha end
                break;

        case 'editpost':
                $page_title = $lang['Edit_Post'];
                $hidden_form_fields .= '<input type="hidden" name="' . POST_POST_URL . '" value="' . $post_id . '" />';
                break;
}

// Generate smilies listing for page output


In includes/functions_post.php
Find
Code:
function prepare_post(&$mode, &$post_data, &$bbcode_on, &$html_on, &$smilies_on, &$error_msg, &$username, &$bbcode_uid, &$subject, &$message, &$poll_title, &$poll_options, &$poll_length)

{
        global $board_config, $userdata, $lang, $phpEx, $phpbb_root_path;

Change to
Code:
function prepare_post(&$mode, &$post_data, &$bbcode_on, &$html_on, &$smilies_on, &$error_msg, &$username, &$bbcode_uid, &$subject, &$message, &$poll_title, &$poll_options, &$poll_length, &$captcha_check)

{
        global $board_config, $userdata, $lang, $phpEx, $phpbb_root_path, $sitekey;

Find
Code:
        return;

}

//
// Post a new topic/reply/poll or edit existing post/poll
//

Change to
Code:
// MOD Captcha start

   if (!empty($captcha_check))
   {
      if ( !$userdata['session_logged_in'] && ($mode == 'newtopic' || $mode == 'reply') )
      {
         $datekey = date("F j");
         $rcode = hexdec(md5($_SERVER['HTTP_USER_AGENT'] . $sitekey . $_POST['captcha_num'] . $datekey));
         $code = substr($rcode, 2, 6);
         if ($code != $captcha_check)
         {
         $error_msg .= (!empty($error_msg)) ? '<br />Wrong security code' : 'Wrong security code';
         }
      }
   }
   else if ($captcha_check == '')
   {
      if ( !$userdata['session_logged_in'] && ($mode == 'newtopic' || $mode == 'reply') )
      {
      $error_msg .= (!empty($error_msg)) ? '<br />You must enter the security code' : 'You must enter the security code';
      }
   }
// MOD Captcha end
        return;
}

//
// Post a new topic/reply/poll or edit existing post/poll
//

Thats about it...
The apperance of the captcha is found in modules/Forums/templates/subSilver/posting_body.tpl
I made mine a bit different from the original, like
Code:
<td class="areatitle" colspan="2" align="center" height="25">

     <input type="submit" tabindex="5" name="preview" class="mainoption" value="{L_PREVIEW}" />
     <hr />
     {S_HIDDEN_FORM_FIELDS}
     <br />
     <input type="submit" accesskey="s" tabindex="6" name="post" class="mainoption" value="{L_SUBMIT}" /></td>

however, all the code is in the {S_HIDDEN_FORM_FIELDS} so if you want it quick'n-dirty, no edits are necesarry in this file.

Please enhance, im no coder so i might have missed something along the line. It works with me, using nuke 7.6, patched 3.3 and BBtoNuke .21

For the record, if no code is written or wrong code is written an error message is appearing just like it would when no subject is applied.


Last edited by NoFantasy on Mon Nov 27, 2006 7:56 am; edited 1 time in total 
View user's profile Send private message
montego
Site Admin


Joined: Aug 29, 2004
Posts: 9457
Location: Arizona

PostPosted: Fri Nov 24, 2006 10:02 am Reply with quote

Very cool! Thanks for sharing with the community.

_________________
Only registered users can see links on this board! Get registered or login!
Only registered users can see links on this board! Get registered or login! 
View user's profile Send private message Visit poster's website
NoFantasy
PostPosted: Fri Nov 24, 2006 10:54 am Reply with quote

yah, felt i've been asking for help all the time, so guess it's time to give a bit back.
Please feel free to make it more "allround" and get rid of any bad/unecesarry coding, as i said it's not tested on other than one of my sites.
 
evaders99
Former Moderator in Good Standing


Joined: Apr 30, 2004
Posts: 3221

PostPosted: Sat Nov 25, 2006 1:17 am Reply with quote

Smart stuff!

_________________
- Only registered users can see links on this board! Get registered or login! -

Need help? Only registered users can see links on this board! Get registered or login! 
View user's profile Send private message Visit poster's website
NoFantasy
PostPosted: Mon Nov 27, 2006 8:00 am Reply with quote

...even smarter when i give you all the code, heh... I forgot to paste the part about making a random number, sorry...

Also fixed a small typo, so code above is all good now.
 
technocrat
Life Cycles Becoming CPU Cycles


Joined: Jul 07, 2005
Posts: 511

PostPosted: Mon Nov 27, 2006 10:36 am Reply with quote

Ah, I am not trying to be mean, but this is a poor way to do it and you can thank FB for it. The problem is your passing the number in two places which makes it visible to bots. This means it is very easy to break.

The first thing you need to do is ditch using FB's design to make a captcha, because to make the image you have to include the numbers. So modules.php?gfx=gfx&amp;random_num=12345 can be read by a bot/scanner. This makes it VERY simple. The other problem is the hidden field that contains the number. Again this is readable.

The easiest fix would be to use sessions to hold and display the number. It would only take a few minutes to recode everything to work correctly.

Again I am not trying to be mean, I am just pointing out the flaws in the system that FB laid out. A more advanced spam bot is going to blast right through this.

_________________
Only registered users can see links on this board! Get registered or login!
Only registered users can see links on this board! Get registered or login! / Only registered users can see links on this board! Get registered or login! 
View user's profile Send private message
evaders99
PostPosted: Mon Nov 27, 2006 1:28 pm Reply with quote

But the random number itself does not match the value of the image. Is there an easy way to figure that out without knowing the randomization key?

Granted the CAPCHTA in phpNuke default is weak, as it ties one random number to a code for 24 hours. You can read it once by eye, and then have the script input the correct number for those 24 hrs.
 
technocrat
PostPosted: Mon Nov 27, 2006 2:58 pm Reply with quote

For starters how many people do you think change the key? You can also post and get the code like you said.

Really the whole design is pretty messed up. It should be just rewritten using sessions and more proper random generator. It would not be too hard to do. In Evo and it will show up in the next release of RN, we are using an out side phpCATPCHA that already uses sessions, and I rewrote the default one to use sessions.

Here is the code from Evo, which would need some back porting to get working on standard nuke. It's a mix of the standard and the more advance phpCATPCHA.

GFX generator
Code:
if (realpath(__FILE__) == realpath($_SERVER['SCRIPT_FILENAME'])) {

    exit('Access Denied');
}

include_once(dirname(dirname((__FILE__))).'/mainfile.php');

global $random_num, $evoconfig;

function random_code($number) {
    $out = '';
    $letters = range('a', 'z');
    for ($i=0; $i < $number; $i++) {
        mt_srand(crc32(microtime()));
        $num = mt_rand(0,1);
        if ($num) {
            //Number 1 - 9
            $out .= mt_rand(1, 9);
        } else {
            $out .= $letters[mt_rand(0, 25)];
        }
    }
    return $out;
}

if(GDSUPPORT) {
    $useimage = intval($evoconfig['useimage']);
    $fontsize = 5;
    $ttf = false;
    if ($evoconfig['codefont']) {
        $codefont = stripslashes($evoconfig['codefont']);
        $font = NUKE_INCLUDE_DIR.'fonts/'.$codefont.'.ttf';
        $ttf = (function_exists('imagettftext') && file_exists($font));
        $ttfsize = $fontsize*2;
    }
   
    $code = random_code($evoconfig['codesize']);
    $ThemeSel = get_theme();
   
    include_once(NUKE_THEMES_DIR.$ThemeSel.'/theme.php');
   
    if ($ttf) {
        $border = imagettfbbox($ttfsize, 0, $font, $code);
        $width = $border[2]-$border[0];
    } else {
        $width = strlen($code)*(4+$fontsize);
    }
   
    if ($useimage) {
   
        if (file_exists("themes/$ThemeSel/images/code_bg.jpg")) {
            $image = ImageCreateFromJPEG("themes/$ThemeSel/images/code_bg.jpg");
        } else if (file_exists("themes/$ThemeSel/images/code_bg.png")) {
            $image = ImageCreateFromPNG("themes/$ThemeSel/images/code_bg.png");
        } else {
            $image = ImageCreateFromJPEG('images/code_bg.jpg');
        }
        if (!isset($gfxcolor)) {
            $gfxcolor = '#505050';
        }
   
    } else {
   
        if (!isset($gfxcolor)) {
            $txtclr = $textcolor1;
        }
        $bgclr  = $bgcolor1;
   
        $bred   = hexdec(substr($bgclr, 1, 2));
        $bgreen = hexdec(substr($bgclr, 3, 2));
        $bblue  = hexdec(substr($bgclr, -2));
   
        $image = ImageCreate($width+6,20);
        $background_color = ImageColorAllocate($image, $bred, $bgreen, $bblue);
        ImageFill($image, 0, 0, $background_color);
   
    }
   
    $tred   = hexdec(substr($gfxcolor, 1, 2));
    $tgreen = hexdec(substr($gfxcolor, 3, 2));
    $tblue  = hexdec(substr($gfxcolor, -2));
   
    $left = (imagesx($image)-$width)/2;
   
    if (function_exists('imagecolorallocatealpha')) {
        $txt_color = imagecolorallocatealpha($image, $tred, $tgreen, $tblue, 50);
        if ($ttf) {
            imagettftext($image, $ttfsize, 0, $left+1, 16, $txt_color, $font, $code);
        } else {
            ImageString($image, $fontsize, $left+2, 3, $code, $txt_color);
        }
    }
   
    if ($ttf) {
        imagettftext($image, $ttfsize, 0, $left, 15, ImageColorAllocate($image, $tred, $tgreen, $tblue), $font, $code);
    } else {
        ImageString($image, $fontsize, $left, 2, $code, ImageColorAllocate($image, $tred, $tgreen, $tblue));
    }
    session_start();
    if(isset($_SESSION['GFXCHECK'])) unset($_SESSION['GFXCHECK']);
    $_SESSION['GFXCHECK'] = $code;
    Header('Content-type: image/png');
    ImagePNG($image);
    ImageDestroy($image);
    exit;
}


GFX code check:
Code:
function security_code_check($gfx_code, $gfxchk) {

    global $evoconfig;
    if (!GDSUPPORT) {
        return true;
    }
    session_start();
    if ($gfxchk != 'force') {
        if (!in_array($evoconfig['usegfxcheck'],$gfxchk)) {
            if (isset($_SESSION['GFXCHECK'])) unset($_SESSION['GFXCHECK']);
            return true;
        }
    }
    if (defined('CAPTCHA')) {
        require_once(NUKE_CLASSES_DIR.'class.php-captcha.php');
        if (PhpCaptcha::Validate($gfx_code)) {
            return true;
        } else {
            return false;
        }
    } else {
        if(!isset($_SESSION['GFXCHECK'])) {
            return false;
        }
        if ($gfx_code != $_SESSION['GFXCHECK']) {
            unset($_SESSION['GFXCHECK']);
            return false;
        }
        unset($_SESSION['GFXCHECK']);
        return true;
    }
}
 
gregexp
The Mouse Is Extension Of Arm


Joined: Feb 21, 2006
Posts: 1497
Location: In front of a screen....HELP! lol

PostPosted: Mon Nov 27, 2006 5:57 pm Reply with quote

In Raven's words, the old code could be hijacked to give the output.

Now as for technocrats code, looks Great but really was all that necessary?

I mean all we really would need to do is send the $random_num through sessions and not $_post. and tell the existing check to look at sessions and not the post variable, Just my thought on the matter considering that the captcha system you speak of sends the actual code itself through sessions, so no decoding.

_________________
For those who stand shall NEVER fall and those who fall shall RISE once more!! 
View user's profile Send private message Send e-mail Visit poster's website AIM Address Yahoo Messenger MSN Messenger ICQ Number
technocrat
PostPosted: Mon Nov 27, 2006 6:07 pm Reply with quote

You have to some how get what the user entered, and it is always going to get posted (never get).
 
gregexp
PostPosted: Mon Nov 27, 2006 7:11 pm Reply with quote

sorry, I was reffering to the $random_num not what the user entered.

The check system in standard nuke, grabs 2 things, first the users input($_POST) and the random_num($_POST) but we could change the random number to be processed through sessions instead of post.
Thats all I meant by it.
 
NoFantasy
PostPosted: Tue Nov 28, 2006 7:43 am Reply with quote

technocrat wrote:
Ah, I am not trying to be mean, but this is a poor way to do it and you can thank FB for it.

No offence taken, in any way Very Happy As it says in the topic, it's a simple captcha, no more, no less. At least i got rid of a couple of spammers using this, it still remains to see if they come back with a more advanced user agent and continue their mission to inform my users of their adult sites (least they could do was to give us more interesting pictures to look on)...

Thanks for the sample code, i really hope someone make it work fully in BBtoNuke, easy to implement and also not only for the upcoming RN.
 
technocrat
PostPosted: Tue Nov 28, 2006 10:05 am Reply with quote

It should be easily backported from RN once it is released. With Evo we improved the base so much it can be hard to backport.
 
Display posts from previous:       
Post new topic   Reply to topic    Ravens PHP Scripts And Web Hosting Forum Index -> Captcha Security

View next topic
View previous topic
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You can attach files in this forum
You can download files in this forum


Powered by phpBB © 2001-2007 phpBB Group
All times are GMT - 6 Hours
 
Forums ©