Page 1 of 1

User Registration Security Hole

PostPosted: Fri Sep 15, 2006 4:54 am
Author: jwernerny
I have been having some problems with getting bogus Spam Accounts (my word) signing up in my forum. After digging into the problem some more, I have found what looks like some sort of injection hack being used.

The forum is setup with with the profilcp images required. It also requires the security question and answer. If I try to skip them from the webpage, the scripts complain. But, I have bogus accounts that appear to be machine generated. (The same user name is registered on 20,000+ sites in 3 days!)

Looking through the raw SQL database and my logs, discovered two interesting things.

1. All of the bogus accounts have no security question.

2. From my logs, it looks like they are doing an end-around insertion

Code: Select all
211.191.97.246 - - [15/Sep/2006] "GET /forum/profile.php?mode=register&agreed=true HTTP/1.1" 302 - "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"    ***MARK***211.191.97.246 - - [15/Sep/2006:00:05:06 -0400] "POST /forum/profile.php HTTP/1.1" 302 - "http://snowtire.info/forum/profile.php?mode=register&agreed=true" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"  


My guesss is that there is an exploit around this.

Looking through google, I see that several other sites are reporting DDOS attacks with the string "/forum/profile.php?mode=register&agreed=true"

A further look gives some sites that appear to claim to have exploits against phpbb. I can't view them from here since they are blocked.

- John

PostPosted: Mon Oct 09, 2006 6:19 pm
Author: Michaelo
This exploit does not work in 1.4.1... what is the affect in 1.4.0?

PostPosted: Wed Oct 11, 2006 11:15 am
Author: jwernerny
It looks like the exploit purpose is to inject a new users into the forum database without them going through the registration (and image verificaiton) process. I have been getting 4 to 5 users who somehow managed to register without filling in required fields. My guess is that it is using this.

I can't wait to get my hands on 1.4.1 (or KisMod) and see if upgrading stops that.

PostPosted: Thu Oct 12, 2006 7:13 pm
Author: odius
so whats the plan until then, or for who doesnt wanna bother updating ? will there be an upgrade to kismod or does the who package have to be replaced, and site content manually restored??

I'm guessing the injection problems can all b blocked with proper .htaccess entrys??

PostPosted: Thu Oct 12, 2006 7:33 pm
Author: Michaelo
If you post your copy of profile.php here I can check for exploit... 1.4.1 does not have mode = register in profiles.php ?

Re: User Registration Security Hole

PostPosted: Fri Oct 13, 2006 9:44 am
Author: Dioncecht
until 1.4.1 is realeased, I'll just delete the bogus accounts. I only get about 5 a day

Re: User Registration Security Hole

PostPosted: Fri Oct 13, 2006 11:20 pm
Author: odius
this is 1.4
with phpbb 2.19

<?php

/***************************************************************************

* profile.php

* -----------

* begin : 08/05/2003

* copyright : Ptirhiik

* email : <a>admin@rpgnet-fr.com</a>

*

* version : 1.0.9 - 17/10/2003

*

***************************************************************************/



define('IN_PHPBB', true);

$phpbb_root_path = './';

include($phpbb_root_path . 'extension.inc');

include($phpbb_root_path . 'common.'.$phpEx);

include($phpbb_root_path . 'includes/functions_points.'.$phpEx);

include($phpbb_root_path . 'profilcp/functions_profile.'.$phpEx);



include($phpbb_root_path . 'includes/functions_selects.'.$phpEx);

include($phpbb_root_path . 'includes/functions_validate.'.$phpEx);

include($phpbb_root_path . 'includes/functions_post.'.$phpEx);

include($phpbb_root_path . 'includes/bbcode.'.$phpEx);

include($phpbb_root_path . 'includes/emailer.'.$phpEx);

include_once($phpbb_root_path . 'includes/functions_topics_list.' . $phpEx);



//

// Start session management

$userdata = session_pagestart($user_ip, PAGE_PROFILE);

init_userprefs($userdata);



//

// Set default email variables

//

$script_name = preg_replace('/^/?(.*?)/?$/', '1', trim($board_config['script_path']));

$script_name = ( $script_name != '' ) ? $script_name . '/profile.'.$phpEx : 'profile.'.$phpEx;

$server_name = trim($board_config['server_name']);

$server_protocol = ( $board_config['cookie_secure'] ) ? 'https://' : 'http://';

$server_port = ( $board_config['server_port'] <> 80 ) ? ':' . trim($board_config['server_port']) . '/' : '/';



$server_url = $server_protocol . $server_name . $server_port . $script_name;



//

// get viewed user id

$view_user_id = ANONYMOUS;

if ( isset($HTTP_POST_VARS[POST_USERS_URL]) || isset($HTTP_GET_VARS[POST_USERS_URL]) )

{

$view_user_id = isset($HTTP_POST_VARS[POST_USERS_URL]) ? intval($HTTP_POST_VARS[POST_USERS_URL]) : intval($HTTP_GET_VARS[POST_USERS_URL]);

}

if ($view_user_id==ANONYMOUS) $view_user_id = $userdata['user_id'];



//

// get the menu

$dir = @opendir($phpbb_root_path . "profilcp");

$setmodules = true;

while( $file = @readdir($dir) )

{

if( preg_match("/^profilcp_.*?." . $phpEx . "$/", $file) )

{

include($phpbb_root_path . "profilcp/" . $file);

}

}

@closedir($dir);



unset($setmodules);

//

// sort

for ($i=0; $i <count>sql_query($sql))

{

message_die(GENERAL_ERROR, 'Couldn't obtain user information.', '', __LINE__, __FILE__, $sql);

}

if (!$user_row = $db->sql_fetchrow($result) )

{

message_die(GENERAL_ERROR, $lang['No_such_user']);

}



// get curopt

$curopt = -1;

for ($i=0; ( ($i < count($module['mode'])) && ($curopt < 0) ); $i++ )

{

if ($mode == $module['mode'][$i])

{

$curopt = $i;

}

}



// sub-option

if ( !isset($module['sub'][$curopt]['mode']) || !in_array($sub, $module['sub'][$curopt]['mode']) )

{

$sub = '';

}



// get cur subopt

$cur_subopt = -1;

for ($i=0; ( ($i < count($module['sub'][$curopt]['mode'])) && ($cur_subopt < 0) ); $i++ ) if ($sub == $module['sub'][$curopt]['mode'][$i]) $cur_subopt = $i;

if ( ($cur_subopt <0> 0) )

{

$cur_subopt = 0;

$sub = $module['sub'][$curopt]['mode'][0];

}



// action

$set = '';

if ( isset($HTTP_POST_VARS['set']) || isset($HTTP_GET_VARS['set']) )

{

$set = isset($HTTP_POST_VARS['set']) ? $HTTP_POST_VARS['set'] : $HTTP_GET_VARS['set'];

}

$no_header = in_array($set, array('add', 'remove'));



// Control

$submit = ( isset($HTTP_POST_VARS['submit']) || (($mode=='privmsg') && isset($HTTP_POST_VARS['post'])) );

$reset = isset($HTTP_POST_VARS['reset']);

$remove = isset($HTTP_POST_VARS['remove']);

$adduser = isset($HTTP_POST_VARS['adduser']);

$preview = isset($HTTP_POST_VARS['preview']);

$cancel = isset($HTTP_POST_VARS['cancel']);

$confirm = isset($HTTP_POST_VARS['confirm']);



// privmsg

$save = isset($HTTP_POST_VARS['save']);

$mark_list = ( !empty($HTTP_POST_VARS['mark']) ) ? $HTTP_POST_VARS['mark'] : 0;

$save = ($save && $mark_list && ($sub != 'savebox') && ($sub != 'outbox'));



// reload the user row

$view_userdata = $user_row;



if ($submit || $remove || $adduser || $no_header || $save || $confirm)

{

// session id check

if ( ($sid != $userdata['session_id']) && ($set == '') && !$no_header && !defined('NO_SID'))

{

message_die(GENERAL_ERROR, 'Invalid_session');

}



if ( !empty($module['url'][$curopt]) && empty($module['sub'][$curopt]['url'][$cur_subopt]) )

{

@include( $phpbb_root_path . './profilcp/' . $module['url'][$curopt] );

}

if ( !empty($module['sub'][$curopt]['url'][$cur_subopt]) )

{

include( $phpbb_root_path . './profilcp/' . $module['sub'][$curopt]['url'][$cur_subopt] );

}



if (!$error && !$no_header)

{

$ret_link = append_sid("./profile.$phpEx?mode=$mode" . (($cur_subopt <0>assign_vars(array(

'META' => '<meta>')

);

/* PCP Extra :: Altered

$message = $lang['Profile_updated'] . '<br><br>' . sprintf($lang['Click_return_profilcp'], '<a>', "</a>") . '<br><br>';*/

$message = $lang['Profile_updated'] . '<br><br>' . sprintf($lang['Click_return_profilcp'], '<a>', "</a>", $module['sub'][$curopt]['page_title'][$cur_subopt]) . '<br><br>';

message_die(GENERAL_MESSAGE, $message);

}

}

else if ($cancel)

{

redirect(append_sid("./profile.$phpEx?mode=$mode&sub=$sub"));

}

else

{

// set the page title and include the page header

$page_title = $module['page_title'][$curopt];

if ($cur_subopt >= 0) $page_title .= ' :: ' . $module['sub'][$curopt]['page_title'][$cur_subopt];

include ($phpbb_root_path . './includes/page_header.' . $phpEx);



// template file

$template->set_filenames(array(

'profilcp_header' => 'profilcp/profilcp_header.tpl')

);

//

// menu

$nb_opt = count($module['shortcut']);

if ( $nb_opt < 8 ) $nb_opt = 8;

$width = intval(120 / $nb_opt) +1;

$filler_width = 120 - $width * count($module['shortcut']);

if ($filler_width <0>assign_vars(array(

'NBOPT' => $nb_opt,

'WIDTH' => $width,

'FILLER_WIDTH' => $filler_width,

)

);

if ( $nb_opt > count($module['shortcut']) )

{

$template->assign_block_vars('filleropt', array() );

}



for ($i=0; $i <count> $level_prior[get_user_level($view_userdata)])))) ? 'otheropt' : 'inactopt' );

$template->assign_block_vars('opt', array());

$link = append_sid("./profile.$phpEx?mode=" . $module['mode'][$i] . ( ($view_userdata['user_id'] != ANONYMOUS) ? '&' . POST_USERS_URL . '=' . $view_userdata['user_id'] : '') );

if ( count($module['sub'][$i]['mode']) == 1 )

{

// only one sub-module

$link = append_sid("./profile.$phpEx?mode=" . $module['mode'][$i] . "&sub=" . $module['sub'][$i]['mode'][0] . ( ($view_userdata['user_id'] != ANONYMOUS) ? '&' . POST_USERS_URL . '=' . $view_userdata['user_id'] : '') );

}

$template->assign_block_vars('opt.' . $switch, array(

'SHORTCUT' => $module['shortcut'][$i],

'U_SHORTCUT' => $link,

)

);

}

//

// sub-menu

if ( ($cur_subopt >= 0) && (count($module['sub'][$curopt]['mode']) > 1) )

{

$nb_opt = count($module['sub'][$curopt]['shortcut']);

if ( $nb_opt < 8 ) $nb_opt = 8;

$width = intval(100 / $nb_opt) +1;

$filler_width = 100 - $width * count($module['sub'][$curopt]['shortcut']);

if ($filler_width <0>assign_block_vars('sub_menu', array(

'U_MODULE' => append_sid("./profile.$phpEx?mode=" . $module['mode'][$curopt] . "&sub=$sub" . ( ($view_userdata['user_id'] != ANONYMOUS) ? '&' . POST_USERS_URL . '=' . $view_userdata['user_id'] : '') ),

'L_MODULE' => $module['sub'][$curopt]['page_title'][$cur_subopt],

'NBOPT' => $nb_opt,

'WIDTH' => $width,

'FILLER_WIDTH' => $filler_width,

)

);



if ( $nb_opt > count($module['sub'][$curopt]['shortcut']) )

{

$template->assign_block_vars('sub_menu.filleropt', array() );

}



for ($i=0; $i <count> $level_prior[get_user_level($view_userdata)])))) ? 'otheropt' : 'inactopt' );

$template->assign_block_vars('sub_menu.opt', array());

if ($i <count>assign_block_vars('sub_menu.opt.' . $switch, array(

'SHORTCUT' => $module['sub'][$curopt]['shortcut'][$i],

'U_SHORTCUT' => append_sid("./profile.$phpEx?mode=" . $module['mode'][$curopt] . "&sub=" . $module['sub'][$curopt]['mode'][$i] . ( ($view_userdata['user_id'] != ANONYMOUS) ? '&' . POST_USERS_URL . '=' . $view_userdata['user_id'] : '') ),

)

);

}

}

}



// system info

$s_hidden_fields = '<input>';

$s_hidden_fields .= '<input>';

$s_hidden_fields .= '<input>';

if ( $cur_subopt >= 0) $s_hidden_fields .= '<input>';



$s_pagination_fields = 'mode=' . $mode;

if ($view_user_id != ANONYMOUS)

{

$s_pagination_fields .= '&' . POST_USERS_URL . "=$view_user_id";

}

$s_pagination_fields .= '&sid=' . $userdata['session_id'];

if ($cur_subopt >= 0)

{

$s_pagination_fields .= '&sub=' . $sub;

}



//

// page header constant

if (!isset($nav_separator)) $nav_separator = ' -> ';

$template->assign_vars(array(

'NAV_SEPARATOR' => $nav_separator,

'L_MODULE' => ( ($view_userdata['user_id'] != ANONYMOUS) ? $view_userdata['username'] : $lang['Guest'] ) . ' : ' . $module['page_title'][$curopt],

'U_MODULE' => append_sid("./profile.$phpEx?mode=" . $module['mode'][$curopt] . ( ($view_userdata['user_id'] != ANONYMOUS) ? '&' . POST_USERS_URL . '=' . $view_userdata['user_id'] : '') ),

)

);



// header

$template->pparse('profilcp_header');



// module

if ( !empty($module['url'][$curopt]) && empty($module['sub'][$curopt]['url'][$cur_subopt]) )

{

@include( $phpbb_root_path . './profilcp/' . $module['url'][$curopt] );

}

if ( !empty($module['sub'][$curopt]['url'][$cur_subopt]) )

{

@include( $phpbb_root_path . './profilcp/' . $module['sub'][$curopt]['url'][$cur_subopt] );

}



// footer

$template->set_filenames(array(

'profilcp_footer' => 'profilcp/profilcp_footer.tpl')

);



// sub-menu

if ( $cur_subopt >= 0 )

{

$template->assign_block_vars('sub_menu_b', array());

}

$template->pparse('profilcp_footer');



//

// page_footer

include($phpbb_root_path . './includes/page_tail.'.$phpEx);

}



?>

Re: User Registration Security Hole

PostPosted: Fri Nov 17, 2006 5:10 pm
Author: Aquilo
....
"Michaelo";p="16350" wrote:This exploit does not work in 1.4.1... what is the affect in 1.4.0?


"Dioncecht";p="16571" wrote:until 1.4.1 is realeased, I'll just delete the bogus accounts. I only get about 5 a day


Well, actually, we get 3 to 15 a day.... (and its me deleting them, not you, Dion) yep, 3 to 15 every single day... I sure have better things to do with my time then delete bogus user accounts all day

it is pretty frustrating that the support site isn't affected by this (maybe there would already be a fix if it was being affected??) especially since its cuz they've upgraded to a version that isn't available to the rest of us - we are just stuck waiting, and waiting, and waiting <img>

Re: User Registration Security Hole

PostPosted: Fri Nov 17, 2006 9:53 pm
Author: Frost
Um.. I have an idea that may work for you :P