[COMMENT] /* +-------------------------------------------------------------------------- | Invision Board v1.3 | ======================================== | > Mod_Installer | > Module written by Peter(Pit) | > Peter member at ibforen.de, Pit member at invisionize.com | > email: Peter@ibforen.de | | > Mod_Installer Version Number: 1.3.3 (2011-06-01) | > 2003 - 2011 by Peter | | > This is the CodeChange.php for Mod Secure Login by Peter +-------------------------------------------------------------------------- */ [COMMENT_END] [INTERFACE] 'title' => 'Secure Invisionboard', 'sub_title' => 'Captcha codes and new Login procedure to prevent your board from getting hacked or spammed', 'category' => 'Major Mod', 'compatible' => '1.3', 'version' => '1.3.3', 'author' => 'Peter', 'email' => 'Peter@ibforen.de', 'mod_token' => 'mod_secure', [INTERFACE_END] [HISTORY] [b]Version 1.3.3[/b] [list][*]Compatible with Mod Security&Updates >2.7.0 [*]Geographical localization of ip addresses with mod Security&Updates using domTT library for tooltips. [*]Better examination of attack logs with filters and sort criteria. [*]Direct link for ip address to mod Suspicious Accounts. [/list] [color=red][b]Attention: New language files[/b][/color] [b]Version 1.3.2[/b] [list][*]Update to avoid bot attacks using function [b]lost password[/b] Änderungen in Register.php, Funktionen lost_password_start und lost_password_end [/list] [b]Version 1.3.1[/b] [list][*]Minor Update for better recognition of ip adresses in ACP logs Link to WHOIS [/list] [b]Version 1.3.0[/b] [list][*]Captcha images from reCAPTCHA (keys from recaptcha.net necessary) New installation necessary (Changes in admin.php and mod files) [/list] [b]Version 1.2.4[/b] [list][*]Compatible with Mod Admin Lang Tool Replace mod_secure_ad_func.php [/list] [b]Version 1.2.3[/b] [list][*]New service for geographical location of attacker mod_secure_ip2loc.php and mod_secure_ad_func.php [/list] [b]Version 1.2.2[/b] [list][*]Registration of bots is recognized ealier to reduce database queries Reinstall the mod (Changes in Register.php) [/list] [b]Version 1.2.1[/b] [list][*]New animated simple captcha (Dicky Kurniawan) Exchange language files and captcha.php. Create the new directory ../mods/secure/captcha/xrvel_captcha from mod archive. That directory must be writable (chmod 777) [/list] [b]Version 1.2[/b] [list] [*]New mod name [*]New animated and not animated captchas [*]Enhanced ACP settings New installation is necessary [/list] [b]Version 1.1.6[/b] [list] [*]Bugfix for alphanumeric security codes (Changes in in Register.php, Usercp.php and mod_secure_func.php) [/list] [b]Version 1.1.5[/b] [list] [*]Use of alphanumeric charachters for security codes [*]New animated captcha code (Activation in captcha.php) (c) by László Zsidi Exchange all files in sources/mods/secure and exchange all language files of this mod. Thereafter install the mod again with my ModInstaller. [/list] [b]Version 1.1.4.1[/b] [list] [*]Bugfix: An error occurred, if banning was activated. Exchange mod_secure_func.php and mod_secure_ad_func.php [/list] [b]Version 1.1.4[/b] [list] [*]View and exploration of log datas improved [b]Attention[/b] Before updating you must remove any older version, but do not remove the sql modification (table ibf_logs)! Then install the mod completely new [/list] [b]Version 1.1.3[/b] [list] [*]Captcha-Codes optimized [b]Attention[/b] Directory structure in sources/mods/secure has changed! [/list] [b]Version 1.1.2[/b] [list] [*]Captcha register and security codes [*]Modifications of Skin/sx/skin_login.php is not any longer needed [/list] [b]Version 1.1[/b] [list] [*]Banning of ip-addresses of possible attackers [*]Moving hack statistics into section Board Logs [*]Bugfix for no showing random code numbers [list][*]admin.php, Step 1 [*]sources/Admin/admin_pages.php, Step 5 [*]Skin/s1/skin_login.php, Step 6 [*]Skin/s1/mod_secure_skin.php (Copy) [*]sources/mods/secure/mod_secure_func.php (Copy) [*]lang/xx/mod_secure_lang.php (Copy) [/list] [/list] [b]Version 1.0[/b] [list] [*]Failed user logins via index.php are logged [*]Failed admin logins via admin.php are logged followed by hard restrictions [*]ACP statistics about hack attacks sort order by account, attack ip, time, login trials [/list] [HISTORY_END] [SQL] [QUERY] CREATE TABLE IF NOT EXISTS ibf_logs ( lid bigint(20) NOT NULL auto_increment, member_id int(10) default NULL, attack_ip varchar(255) default NULL, first_time int(10) default 0, trials int(4) default 0, logincode varchar(8) default '', emailed tinyint(1) default NULL, admin tinyint(1) default NULL, PRIMARY KEY (lid)) [QUERY] DELETE FROM ibf_mods WHERE mod_token='mod_secure' [SQL_END] [CODE] [MOD_TOKEN] mod_secure [FNAME] admin.php [STEP] [SEARCH] require ROOT_PATH."conf_global.php"; [INSERT] //-- mod_secure begin if (file_exists(ROOT_PATH."sources/mods/secure/mod_secure_ad_func.php")) { require ROOT_PATH."sources/mods/secure/mod_secure_ad_func.php"; } else { die("Could not call required function from file 'sources/mods/secure/mod_secure_ad_func.php'
Does it exist?"); } //-- mod_secure end [MODE] insert_below [STEP] [SEARCH] // Get a DB connection $DB->connect(); [INSERT] //-- mod_secure begin if ($IN['act'] == 'Login' AND $IN['CODE'] == 'image') $secure_login->lib->show_image(); if ($IN['act'] == 'secure' AND $IN['CODE'] == 'captcha') { require_once(ROOT_PATH."/sources/mods/secure/captcha.php"); $config['bot_antispam'] = $INFO['bot_antispam']; $config['width'] = $INFO['gd_width']; $config['height'] = $INFO['gd_height']; $config['use_alpha'] = $INFO['gd_captcha_alpha']; $config['use_alpha_case'] = $INFO['gd_captcha_alpha_case']; if ($INFO['gd_captcha_color']) $config['color'] = $INFO['gd_captcha_color']; if ($INFO['gd_captcha_bgcolor']) $config['bgcolor'] = $INFO['gd_captcha_bgcolor']; if ($INFO['gd_captcha_anicolor']) $config['anicolor'] = $INFO['gd_captcha_anicolor']; $config['font'] = $INFO['gd_captcha_font']; $config['background_image'] = $INFO['gd_captcha_background']; $config['use_random'] = $INFO['gd_captcha_random']; $config['method'] = $INFO['gd_captcha_method']; $config['random_methods'] = $INFO['gd_captcha_random_methods']; if (isset($IN['bot_antispam'])) $config['bot_antispam'] = $IN['bot_antispam']; if (isset($IN['antispam_recaptcha'])) $config['antispam_recaptcha'] = $IN['antispam_recaptcha']; if (isset($IN['gd_width'])) $config['width'] = $IN['gd_width']; if (isset($IN['gd_height'])) $config['height'] = $IN['gd_height']; if (isset($IN['random'])) $config['use_random'] = $IN['random']; if (isset($IN['method'])) $config['method'] = $IN['method']; if (isset($IN['random_methods'])) $config['random_methods'] = $IN['random_methods']; if (isset($IN['alpha'])) $config['use_alpha'] = $IN['alpha']; if (isset($IN['alpha_case'])) $config['use_alpha_case'] = $IN['alpha_case']; if (isset($IN['color'])) $config['color'] = $IN['color']; if (isset($IN['bgcolor'])) $config['bgcolor'] = $IN['bgcolor']; if (isset($IN['anicolor'])) $config['anicolor'] = $IN['anicolor']; if (isset($IN['font'])) $config['font'] = $IN['font']; if (isset($IN['background'])) $config['background_image'] = $IN['background']; $captcha = new captcha($config); exit(); } //-- mod_secure end [MODE] insert_below [STEP] [SEARCH] $pass = md5( $IN['password'] ); if ($pass != $mem['password']) [INSERT] //-- mod_secure begin if ($ibforums->vars['secure_logging']) { global $secure_login; $secure_login->do_log($mem, TRUE); } //-- mod_secure end [MODE] insert_above [STEP] [SEARCH] function do_login($message="") { [INSERT] /*-- mod_secure exclude begin [MODE] insert_above [STEP] [SEARCH] function do_login($message="") { [INSERT] -- mod_secure exclude end */ //-- mod_secure begin function do_login($message="", $random_number = FALSE, $logid = "") { global $std, $IN, $ADMIN, $INFO, $ibforums, $secure_login; $lang = $std->load_words($lang, 'mod_secure_lang', $INFO['default_language']==""?'en':$INFO['default_language']); if ($INFO['admin_ban_ip']) { $ips = explode( "|", $INFO['admin_ban_ip'] ); foreach ($ips as $ip) { $ip = preg_replace( "/\*/", '.*' , $ip ); if (preg_match( "/$ip/", $IN['IP_ADDRESS'] )) { $ADMIN->error( $lang['secure_banned_info'] ); } } } //-- mod_secure end [MODE] insert_below [STEP] [SEARCH] if ($message != "") { [INSERT] //-- mod_secure begin $temp = $lang[ $message ]; if ($temp != "" ) $message = $temp; $message = preg_replace( "/<#NAME#>/", "{$IN[username]}", $message ); //-- mod_secure end [MODE] insert_below [STEP] [SEARCH] "", ) ); [INSERT] //-- mod_secure begin if ($random_number) { $ADMIN->html .= $secure_login->login_random_number($logid,$lang['code_title'], $lang['code_info']); } $ADMIN->html .= "\n\n\n\n"; //-- mod_secure end [MODE] insert_below [STEP] [SEARCH] $IN['act'] = $IN['act'] == '' ? "idx" : $IN['act']; [INSERT] //-- mod_secure begin if ($IN['act'] == "secure") { global $secure_login; $secure_login->dispatch(); } //-- mod_secure end [MODE] insert_below [FNAME_END] [MOD_TOKEN] mod_secure [FNAME] index.php [STEP] [SEARCH] require ROOT_PATH."sources/".$choice[ $ibforums->input['act'] ].".php"; [INSERT] //-- mod_secure begin if (file_exists(ROOT_PATH."sources/mods/secure/mod_secure_func.php")) { require ROOT_PATH."sources/mods/secure/mod_secure_func.php"; global $secure_login; $secure_login = new mod_secure_lib; } else { die("Could not call required function from file 'sources/mods/secure/mod_secure_func.php'
Does it exist?"); } //-- mod_secure end [MODE] insert_above [FNAME_END] [MOD_TOKEN] mod_secure [FNAME] sources/functions.php [STEP] [SEARCH] /*-------------------------------------------------------------------------*/ // expire_subscription [INSERT] //-- mod_secure begin function md5_xor($a, $b) { for ($i = 0; $i < strlen($a); $i++) { $return .= base_convert((int) base_convert(substr($a, $i, 1), 16, 10) ^ (int) base_convert(substr($b, $i, 1), 16, 10), 10, 16); } return $return; } //-- mod_secure end [MODE] insert_above [STEP] [SEARCH] function show_gd_img($content="") { global $ibforums, $DB; [INSERT] //-- mod_secure begin global $INFO; require_once(ROOT_PATH."sources/mods/secure/captcha.php"); $config['bot_antispam'] = $INFO['bot_antispam']; $config['width'] = $INFO['gd_width']; $config['height'] = $INFO['gd_height']; $config['background_image'] = $INFO['gd_captcha_background']; $config['use_alpha'] = $INFO['gd_captcha_alpha']; $config['use_alpha_case'] = $INFO['gd_captcha_alpha_case']; $config['font'] = $INFO['gd_captcha_font']; if ($INFO['gd_captcha_color']) $config['color'] = $INFO['gd_captcha_color']; if ($INFO['gd_captcha_bgcolor']) $config['bgcolor'] = $INFO['gd_captcha_bgcolor']; if ($INFO['gd_captcha_anicolor']) $config['anicolor'] = $INFO['gd_captcha_anicolor']; $config['background_image'] = $INFO['gd_captcha_background']; $config['use_random'] = $INFO['gd_captcha_random']; $config['method'] = $INFO['gd_captcha_method']; $config['random_methods'] = $INFO['gd_captcha_random_methods']; $config['code'] = $content; $captcha = new captcha($config); exit(); //-- mod_secure end [MODE] insert_below [FNAME_END] [MOD_TOKEN] mod_secure [FNAME] sources/Login.php [STEP] [SEARCH] default: $this->log_in_form($msg); break; [INSERT] //-- mod_secure begin case 'image': global $secure_login; $secure_login->show_image(); break; //-- mod_secure end [MODE] insert_above [STEP] [SEARCH] function log_in_form($message="") { [INSERT] /*-- mod_secure exclude begin [MODE] insert_above [STEP] [SEARCH] function log_in_form($message="") { [INSERT] -- mod_secure exclude end */ //-- mod_secure begin function log_in_form($message="", $random_number = FALSE, $logid = "") { //-- mod_secure end [MODE] insert_below [STEP] [SEARCH] if ($message != "") { [INSERT] /*-- mod_secure exclude begin [MODE] insert_below [STEP] [SEARCH] $message = preg_replace( "/<#NAME#>/", "{$ibforums->input[UserName]}", $message ); $this->output .= $this->login_html->errors($message); } $this->output .= $this->login_html->ShowForm( $ibforums->lang['please_log_in'], $HTTP_REFERER ); [INSERT] -- mod_secure exclude end */ //-- mod_secure begin global $std; $lang = $std->load_words($lang, 'mod_secure_lang', $ibforums->lang_id); if (isset($lang[ $message ])) { $message = $lang[ $message ]; } elseif (isset($ibforums->lang[ $message ])) { $message = $ibforums->lang[ $message ]; } //-- mod_secure end [MODE] insert_above [STEP] [SEARCH] $message = preg_replace( "/<#NAME#>/", "{$ibforums->input[UserName]}", $message ); $this->output .= $this->login_html->errors($message); } $this->output .= $this->login_html->ShowForm( $ibforums->lang['please_log_in'], $HTTP_REFERER ); [INSERT] //-- mod_secure begin if ($random_number) { $match = "`()`is"; $secure_skin = $std->load_template("mod_secure_skin"); if ($ibforums->vars['bot_antispam'] == 'rec' ) { $this->html2 = $std->load_template('mod_secure_skin'); require_once (ROOT_PATH."sources/mods/secure/captcha/recaptcha/recaptchalib.php"); require (ROOT_PATH."sources/mods/secure/captcha/recaptcha/key.php"); if ($reCaptcha_public_key) { $recaptcha = ""; $recaptcha .= recaptcha_get_html($reCaptcha_public_key); } $this->output = preg_replace( $match, "\\1".str_replace("", $recaptcha, $secure_skin->login_random_number_recaptcha($logid,$lang['code_title'],$lang['code_info'])), $this->output ); } else if ($ibforums->vars['bot_antispam'] == 'gd' ) $this->output = preg_replace( $match, "\\1".$secure_skin->login_random_number_gd($logid,$lang['code_title'],$lang['code_info']), $this->output ); else $this->output = preg_replace( $match, "\\1".$secure_skin->login_random_number($logid,$lang['code_title'],$lang['code_info']), $this->output ); } $this->output .= "\n\n\n\n"; //-- mod_secure end [MODE] insert_below [STEP] [SEARCH] if ( $DB->get_num_rows() ) { $member = $DB->fetch_row(); [INSERT] //-- mod_secure begin if ($ibforums->vars['secure_logging']) { global $secure_login; $secure_login->do_log($member, FALSE, $this); } //-- mod_secure end [MODE] insert_below [FNAME_END] [MOD_TOKEN] mod_secure [FNAME] sources/Register.php [STEP] [SEARCH] $this->email = new emailer(); [INSERT] //-- mod_secure begin global $secure_login; if (!isset($secure_login)) { if (file_exists(ROOT_PATH."sources/mods/secure/mod_secure_func.php")) { require_once ROOT_PATH."sources/mods/secure/mod_secure_func.php"; $secure_login = new mod_secure_lib; } else { die("Could not call required function from file 'sources/mods/secure/mod_secure_func.php'
Does it exist?"); } } //-- mod_secure end [MODE] insert_below [STEP] [SEARCH] $reg_code = mt_rand(100000,999999); [INSERT] //-- mod_secure begin // we do not allow bots to validate email addresses. So we will test on 30 seconds flood time $flood_time = time() - 30; $DB->query("SELECT regid FROM ibf_reg_antispam WHERE ip_address='{$ibforums->input['IP_ADDRESS']}' AND ctime > '$flood_time'"); if ($DB->get_num_rows()) $std->Error( array( 'LEVEL' => 1, 'MSG' => 'search_flood', 'EXTRA' => 30) ); if ($ibforums->vars['gd_captcha']) { global $secure_login; $reg_code = $secure_login->get_code(); } //-- mod_secure end [MODE] insert_below [STEP] [SEARCH] if ($ibforums->vars['bot_antispam'] == 'gd') [INSERT] //-- mod_secure begin if ($ibforums->vars['bot_antispam'] == 'rec') { $this->html2 = $std->load_template('mod_secure_skin'); $ibforums->lang = $std->load_words($ibforums->lang, 'mod_secure_lang', $ibforums->lang_id ); require_once (ROOT_PATH."sources/mods/secure/captcha/recaptcha/recaptchalib.php"); require (ROOT_PATH."sources/mods/secure/captcha/recaptcha/key.php"); if ($reCaptcha_public_key) { $recaptcha = ""; $recaptcha .= recaptcha_get_html($reCaptcha_public_key); } $this->output = str_replace( "", str_replace("", $recaptcha, $this->html2->bot_antispam_recaptcha( $regid )), $this->output ); } else //-- mod_secure end [MODE] insert_above [STEP] [SEARCH] if ( trim( intval($ibforums->input['reg_code']) ) != $row['regcode'] ) { $this->lost_password_start('err_reg_code'); [INSERT] //-- mod_secure begin // this regid is used and not usable anymore $DB->query("DELETE FROM ibf_reg_antispam WHERE regid='".trim(addslashes($ibforums->input['regid']))."'"); // we do not allow bots to validate email addresses. So we will test on 30 seconds flood time $flood_time = time() - 30; $DB->query("SELECT regid FROM ibf_reg_antispam WHERE ip_address='{$ibforums->input['IP_ADDRESS']}' AND ctime > '$flood_time'"); if ($DB->get_num_rows()) $std->Error( array( 'LEVEL' => 1, 'MSG' => 'search_flood', 'EXTRA' => 30) ); if ($ibforums->vars['gd_captcha']) { global $secure_login; if ( !$secure_login->test_reg_code($ibforums->input['reg_code'], $row['regcode'])) { $this->lost_password_start('err_reg_code'); return; } } else //-- mod_secure end [MODE] insert_above [STEP] [SEARCH] function create_account() { global $ibforums, $std, $DB, $print, $HTTP_POST_VARS; [INSERT] //-- mod_secure begin if ($ibforums->vars['bot_antispam']) { if ($ibforums->input['regid'] == "") { $this->show_reg_form('err_reg_code'); return; } $DB->query("SELECT * FROM ibf_reg_antispam WHERE regid='".trim(addslashes($ibforums->input['regid']))."'"); if (!$row = $DB->fetch_row()) { $this->show_reg_form('err_reg_code'); return; } if ($ibforums->vars['gd_captcha']) { global $secure_login; if ( !$secure_login->test_reg_code($ibforums->input['reg_code'], $row['regcode'])) { $this->show_reg_form('err_reg_code'); return; } } else if (trim( intval($ibforums->input['reg_code']) ) != $row['regcode']) { $this->show_reg_form('err_reg_code'); return; } $DB->query("DELETE FROM ibf_reg_antispam WHERE regid='".trim(addslashes($ibforums->input['regid']))."'"); } //-- mod_secure end [MODE] insert_below [STEP] [SEARCH] //| Check the reg_code //+-------------------------------------------- [INSERT] //-- mod_secure begin if (false) //-- mod_secure end [MODE] insert_below [FNAME_END] [MOD_TOKEN] mod_secure [FNAME] sources/Usercp.php [STEP] [SEARCH] $reg_code = mt_rand(100000,999999); [INSERT] //-- mod_secure begin if ($ibforums->vars['gd_captcha']) { global $secure_login; if (!isset($secure_login)) { if (file_exists(ROOT_PATH."sources/mods/secure/mod_secure_func.php")) { require_once ROOT_PATH."sources/mods/secure/mod_secure_func.php"; $secure_login = new mod_secure_lib; } else { die("Could not call required function from file 'sources/mods/secure/mod_secure_func.php'
Does it exist?"); } } $reg_code = $secure_login->get_code(); } //-- mod_secure end [MODE] insert_below [STEP] [SEARCH] if ($ibforums->vars['bot_antispam'] == 'gd') [INSERT] //-- mod_secure begin if ($ibforums->vars['bot_antispam'] == 'rec') { $this->html2 = $std->load_template('mod_secure_skin'); $ibforums->lang = $std->load_words($ibforums->lang, 'mod_secure_lang', $ibforums->lang_id ); require_once (ROOT_PATH."sources/mods/secure/captcha/recaptcha/recaptchalib.php"); require (ROOT_PATH."sources/mods/secure/captcha/recaptcha/key.php"); if ($reCaptcha_public_key) { $recaptcha = ""; $recaptcha .= recaptcha_get_html($reCaptcha_public_key); } $this->output = str_replace( "", str_replace("", $recaptcha, $this->html2->email_change_recaptcha( $regid )), $this->output ); } else //-- mod_secure end [MODE] insert_above [STEP] [SEARCH] if ( trim( intval($ibforums->input['reg_code']) ) != $row['regcode'] ) [INSERT] //-- mod_secure begin if ($ibforums->vars['gd_captcha']) { global $secure_login; if (!isset($secure_login)) { if (file_exists(ROOT_PATH."sources/mods/secure/mod_secure_func.php")) { require_once ROOT_PATH."sources/mods/secure/mod_secure_func.php"; $secure_login = new mod_secure_lib; } else { die("Could not call required function from file 'sources/mods/secure/mod_secure_func.php'
Does it exist?"); } } if ( !$secure_login->test_reg_code($ibforums->input['reg_code'], $row['regcode'])) { $this->email_change('err_security_code'); return; } } else //-- mod_secure end [MODE] insert_above [FNAME_END] [MOD_TOKEN] mod_secure [FNAME] sources/Admin/ad_settings.php [STEP] [SEARCH] case 'dosecure': [INSERT] //-- mod_secure begin global $secure_login; $secure_login->save_config(); //-- mod_secure end [MODE] insert_below [STEP] [SEARCH] function secure() { global $IN, $INFO, $DB, $SKIN, $ADMIN, $std, $MEMBER, $GROUP; [INSERT] //-- mod_secure begin global $secure_login; $secure_login->ad_settings($this); //-- mod_secure end /*-- mod_secure exclude begin [MODE] insert_below [STEP] [SEARCH] $SKIN->form_input( "gd_font", isset($INFO['gd_font']) ? $INFO['gd_font'] : getcwd().'/fonts/progbot.ttf' ) ) ); [INSERT] -- mod_secure exclude end */ [MODE] insert_below [FNAME_END] [MOD_TOKEN] mod_secure [FNAME] sources/Admin/admin_functions.php [STEP] [SEARCH] //--------------------------- // Makes good raw form text [INSERT] //-- mod_secure begin function md5_xor($a, $b) { for ($i = 0; $i < strlen($a); $i++) { $return .= base_convert((int) base_convert(substr($a, $i, 1), 16, 10) ^ (int) base_convert(substr($b, $i, 1), 16, 10), 10, 16); } return $return; } //-- mod_secure end [MODE] insert_above [FNAME_END] [MOD_TOKEN] mod_secure [FNAME] sources/Admin/admin_pages.php [STEP] [SEARCH] ?> [INSERT] //-- mod_secure begin $PAGES[11][] = array( 'Hack Attack Logs' ,'act=secure&code=logs'); //-- mod_secure end [MODE] insert_above [FNAME_END] [CODE_END] [COPY] Copy all files in folder upload of archive into the root dir of your board. Take care of the structure of this archive. [List] [*]sources [arrow] sources ( chmod 777 mods/secure/captcha/xrvel_captcha) [*]lang/en [arrow] lang/en [*]lang/de [arrow] lang/xx (xx = dir of your German lang files) [*]Skin/s1/mod_secure_skin.php [arrow] Skin/sx (copy into all skin folders) [/list] [COPY_END] [CUSTOMIZE] The captcha code reCAPTCHA is provided as a service by recaptcha.net. First you must register at the site, in order to receive a public key ad a private key. Without the keys you cannot use the service. Enter the key values in sources/mods/secure/captcha/recaptcha/key.php. [CUSTOMIZE_END] [COMMENT_MOD] [COMMENT_MOD_END] [HISTORY_OLD] [HISTORY_OLD_END]