################################################################################ ## ## Hack Title: phpBB 2.0.20 - 2.0.21 Code Changes ## Hack Version: 1.0.0 ## Hack Author: Complied by Thoul, code by phpBB Group ## Hack Description: All changes in phpBB made between 2.0.20 and 2.0.21. ## ## Compatibility: 2.0.20 ## Installation Level: Moderate ## Installation Time: 30 minutes ## ## Files To Edit: 13 ## admin/admin_ranks.php ## admin/admin_smilies.php ## admin/admin_styles.php ## admin/admin_words.php ## common.php ## login.php ## privmsg.php ## profile.php ## search.php ## viewtopic.php ## includes/functions.php ## includes/functions_post.php ## includes/sessions.php ## includes/usercp_avatar.php ## includes/usercp_confirm.php ## includes/usercp_register.php ## ## Support: http://www.phpbbhacks.com/forums ## ################################################################################ ## ## You downloaded this hack from phpBBHacks.com, ## the #1 source for phpBB related downloads. ## ## Please visit http://www.phpbbhacks.com/forums for support. ## ################################################################################ ## ## This hack is released under the GPL License. ## ################################################################################ ## ## BEFORE ADDING THIS HACK TO YOUR FORUM, please be sure to backup ALL ## affected files. ## ################################################################################ ## ##----------[ PLEASE NOTE ]------------------------------ ## ## Once you have completed the code changes, create an install/ directory in ## your forum's root directory, and upload the update_to_latest.php file that ## comes in any phpBB 2.0.21 download to the install/ directory. Run ## update_to_latest.php by opening it via your web browser, just as you would a ## normal forum page. Afterward, delete the file and the install/ directory so ## that your forum is accessible again. ## ##----------[ OPEN ]------------------------------------- ## admin/admin_ranks.php ## ##----------[ FIND ]------------------------------------- ## require($phpbb_root_path . 'extension.inc'); ## ##----------[ AFTER, ADD ]------------------------------- ## $cancel = ( isset($HTTP_POST_VARS['cancel']) ) ? true : false; $no_page_header = $cancel; ## ##----------[ FIND ]------------------------------------- ## require('./pagestart.' . $phpEx); ## ##----------[ AFTER, ADD ]------------------------------- ## if ($cancel) { redirect('admin/' . append_sid("admin_ranks.$phpEx", true)); } ## ##----------[ OPEN ]------------------------------------- ## admin/admin_smilies.php ## ##----------[ FIND ]------------------------------------- ## require($phpbb_root_path . 'extension.inc'); ## ##----------[ AFTER, ADD ]------------------------------- ## $cancel = ( isset($HTTP_POST_VARS['cancel']) ) ? true : false; $no_page_header = $cancel; ## ##----------[ FIND ]------------------------------------- ## require('./pagestart.' . $phpEx); ## ##----------[ AFTER, ADD ]------------------------------- ## if ($cancel) { redirect('admin/' . append_sid("admin_smilies.$phpEx", true)); } ## ##----------[ OPEN ]------------------------------------- ## admin/admin_styles.php ## ##----------[ FIND ]------------------------------------- ## "confirm" => "confirm_body.tpl") ## ##----------[ REPLACE WITH ]----------------------------- ## "confirm" => "admin/confirm_body.tpl") ## ##----------[ OPEN ]------------------------------------- ## admin/admin_words.php ## ##----------[ FIND ]------------------------------------- ## require($phpbb_root_path . 'extension.inc'); ## ##----------[ AFTER, ADD ]------------------------------- ## $cancel = ( isset($HTTP_POST_VARS['cancel']) ) ? true : false; $no_page_header = $cancel; ## ##----------[ FIND ]------------------------------------- ## require('./pagestart.' . $phpEx); ## ##----------[ AFTER, ADD ]------------------------------- ## if ($cancel) { redirect('admin/' . append_sid("admin_words.$phpEx", true)); } ## ##----------[ OPEN ]------------------------------------- ## common.php ## ##----------[ FIND ]------------------------------------- ## if (!in_array($var, $not_unset)) { unset($$var); } ## ##----------[ REPLACE WITH ]----------------------------- ## if (in_array($var, $not_unset)) { die('Hacking attempt!'); } unset($$var); ## ##----------[ OPEN ]------------------------------------- ## login.php ## ##----------[ FIND ]------------------------------------- ## $redirect = ( !empty($HTTP_POST_VARS['redirect']) ) ? str_replace('&', '&', htmlspecialchars($HTTP_POST_VARS['redirect'])) : ''; $redirect = str_replace('?', '&', $redirect); if (strstr(urldecode($redirect), "\n") || strstr(urldecode($redirect), "\r")) { message_die(GENERAL_ERROR, 'Tried to redirect to potentially insecure url.'); } $template->assign_vars(array( 'META' => "") ); $message = $lang['Error_login'] . '

' . sprintf($lang['Click_return_login'], "", '') . '

' . sprintf($lang['Click_return_index'], '', ''); message_die(GENERAL_MESSAGE, $message); } ## ##----------[ REPLACE WITH ]----------------------------- ## } $redirect = ( !empty($HTTP_POST_VARS['redirect']) ) ? str_replace('&', '&', htmlspecialchars($HTTP_POST_VARS['redirect'])) : ''; $redirect = str_replace('?', '&', $redirect); if (strstr(urldecode($redirect), "\n") || strstr(urldecode($redirect), "\r")) { message_die(GENERAL_ERROR, 'Tried to redirect to potentially insecure url.'); } $template->assign_vars(array( 'META' => "") ); $message = $lang['Error_login'] . '

' . sprintf($lang['Click_return_login'], "", '') . '

' . sprintf($lang['Click_return_index'], '', ''); message_die(GENERAL_MESSAGE, $message); ## ##----------[ OPEN ]------------------------------------- ## privmsg.php ## ##----------[ FIND ]------------------------------------- ## obtain_word_list($orig_word, $replace_word); ## ##----------[ REPLACE WITH ]----------------------------- ## obtain_word_list($orig_word, $replacement_word); ## ##----------[ OPEN ]------------------------------------- ## profile.php ## ##----------[ FIND ]------------------------------------- ## return ( $hash ) ? md5($rand_str) : substr($rand_str, 8); ## ##----------[ REPLACE WITH ]----------------------------- ## return ( $hash ) ? md5($rand_str) : substr($rand_str, 0, 8); ## ##----------[ OPEN ]------------------------------------- ## search.php ## ##----------[ FIND ]------------------------------------- ## if( ( strpos($search_author, '%') !== false ) && ( strlen(str_replace('%', '', $search_author)) < 3 ) ) ## ##----------[ REPLACE WITH ]----------------------------- ## if( ( strpos($search_author, '%') !== false ) && ( strlen(str_replace('%', '', $search_author)) < $board_config['search_min_chars'] ) ) ## ##----------[ FIND ]------------------------------------- ## if (preg_match('#^[\*%]+$#', trim($split_search[$i])) || preg_match('#^[^\*]{1,2}$#', str_replace(array('*', '%'), '', trim($split_search[$i])))) ## ##----------[ REPLACE WITH ]----------------------------- ## if ( strlen(str_replace(array('*', '%'), '', trim($split_search[$i]))) < $board_config['search_min_chars'] ) ## ##----------[ FIND ]------------------------------------- ## if( ( strpos($search_author, '%') !== false ) && ( strlen(str_replace('%', '', $search_author)) < 3 ) ) ## ##----------[ REPLACE WITH ]----------------------------- ## if( ( strpos($search_author, '%') !== false ) && ( strlen(str_replace('%', '', $search_author)) < $board_config['search_min_chars'] ) ) ## ##----------[ OPEN ]------------------------------------- ## viewtopic.php ## ##----------[ FIND ]------------------------------------- ## // This was shamelessly 'borrowed' from volker at multiartstudio dot de // via php.net's annotated manual $message = str_replace('\"', '"', substr(@preg_replace('#(\>(((?>([^><]+|(?R)))*)\<))#se', "@preg_replace('#\b(" . str_replace('\\', '\\\\', addslashes($highlight_match)) . ")\b#i', '\\\\1', '\\0')", '>' . $message . '<'), 1, -1)); ## ##----------[ REPLACE WITH ]----------------------------- ## // This has been back-ported from 3.0 CVS $message = preg_replace('#(?!<.*)(?]*>)#i', '\1', $message); ## ##----------[ OPEN ]------------------------------------- ## includes/functions.php ## ##----------[ FIND ]------------------------------------- ## return substr($val, 16); ## ##----------[ REPLACE WITH ]----------------------------- ## return substr($val, 4, 16); ## ##----------[ FIND ]------------------------------------- ## global $template, $lang, $phpEx, $phpbb_root_path; ## ##----------[ REPLACE WITH ]----------------------------- ## global $template, $lang, $phpEx, $phpbb_root_path, $db; ## ##----------[ FIND ]------------------------------------- ## $board_config['default_lang'] = $userdata['user_lang']; ## ##----------[ REPLACE WITH ]----------------------------- ## $default_lang = phpbb_ltrim(basename(phpbb_rtrim($userdata['user_lang'])), "'"); ## ##----------[ FIND ]------------------------------------- ## $board_config['board_timezone'] = $userdata['user_timezone']; } } ## ##----------[ AFTER, ADD ]------------------------------- ## else { $default_lang = phpbb_ltrim(basename(phpbb_rtrim($board_config['default_lang'])), "'"); } ## ##----------[ FIND ]------------------------------------- ## if ( !file_exists(@phpbb_realpath($phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . '/lang_main.'.$phpEx)) ) { $board_config['default_lang'] = 'english'; ## ##----------[ REPLACE WITH ]----------------------------- ## if ( !file_exists(@phpbb_realpath($phpbb_root_path . 'language/lang_' . $default_lang . '/lang_main.'.$phpEx)) ) { if ( $userdata['user_id'] != ANONYMOUS ) { // For logged in users, try the board default language next $default_lang = phpbb_ltrim(basename(phpbb_rtrim($board_config['default_lang'])), "'"); } else { // For guests it means the default language is not present, try english // This is a long shot since it means serious errors in the setup to reach here, // but english is part of a new install so it's worth us trying $default_lang = 'english'; } if ( !file_exists(@phpbb_realpath($phpbb_root_path . 'language/lang_' . $default_lang . '/lang_main.'.$phpEx)) ) { message_die(CRITICAL_ERROR, 'Could not locate valid language pack'); } } // If we've had to change the value in any way then let's write it back to the database // before we go any further since it means there is something wrong with it if ( $userdata['user_id'] != ANONYMOUS && $userdata['user_lang'] !== $default_lang ) { $sql = 'UPDATE ' . USERS_TABLE . " SET user_lang = '" . $default_lang . "' WHERE user_lang = '" . $userdata['user_lang'] . "'"; if ( !($result = $db->sql_query($sql)) ) { message_die(CRITICAL_ERROR, 'Could not update user language info'); } $userdata['user_lang'] = $default_lang; } elseif ( $userdata['user_id'] === ANONYMOUS && $board_config['default_lang'] !== $default_lang ) { $sql = 'UPDATE ' . CONFIG_TABLE . " SET config_value = '" . $default_lang . "' WHERE config_name = 'default_lang'"; if ( !($result = $db->sql_query($sql)) ) { message_die(CRITICAL_ERROR, 'Could not update user language info'); } $board_config['default_lang'] = $default_lang; ## ##----------[ FIND ]------------------------------------- ## $sql = "SELECT * FROM " . THEMES_TABLE . " WHERE themes_id = $style"; ## ##----------[ REPLACE WITH ]----------------------------- ## $sql = 'SELECT * FROM ' . THEMES_TABLE . ' WHERE themes_id = ' . (int) $style; ## ##----------[ FIND ]------------------------------------- ## WHERE themes_id = ' . $board_config['default_style']; ## ##----------[ REPLACE WITH ]----------------------------- ## WHERE themes_id = ' . (int) $board_config['default_style']; ## ##----------[ FIND ]------------------------------------- ## SET user_style = ' . $board_config['default_style'] . " ## ##----------[ REPLACE WITH ]----------------------------- ## SET user_style = ' . (int) $board_config['default_style'] . " ## ##----------[ OPEN ]------------------------------------- ## includes/functions_post.php ## ##----------[ FIND ]------------------------------------- ## $message .= htmlspecialchars($part) . clean_html($tag); ## ##----------[ REPLACE WITH ]----------------------------- ## $message .= preg_replace($html_entities_match, $html_entities_replace, $part) . clean_html($tag); ## ##----------[ FIND ]------------------------------------- ## $message = addslashes($message); ## ##----------[ AFTER, ADD ]------------------------------- ## $message = str_replace('"', '\"', $message); ## ##----------[ FIND ]------------------------------------- ## $sql = "UPDATE " . FORUMS_TABLE . " SET $forum_update_sql WHERE forum_id = $forum_id"; if (!$db->sql_query($sql)) { message_die(GENERAL_ERROR, 'Error in posting', '', __LINE__, __FILE__, $sql); ## ##----------[ REPLACE WITH ]----------------------------- ## if ($mode != 'poll_delete') { $sql = "UPDATE " . FORUMS_TABLE . " SET $forum_update_sql WHERE forum_id = $forum_id"; if (!$db->sql_query($sql)) { message_die(GENERAL_ERROR, 'Error in posting', '', __LINE__, __FILE__, $sql); } ## ##----------[ OPEN ]------------------------------------- ## includes/sessions.php ## ##----------[ FIND ]------------------------------------- ## session_clean($userdata['session_id']); setcookie($cookiename . '_data', serialize($sessiondata), $current_time + 31536000, $cookiepath, $cookiedomain, $cookiesecure); setcookie($cookiename . '_sid', $session_id, 0, $cookiepath, $cookiedomain, $cookiesecure); } ## ##----------[ AFTER, ADD ]------------------------------- ## // Add the session_key to the userdata array if it is set if ( isset($sessiondata['autologinid']) && $sessiondata['autologinid'] != '' ) { $userdata['session_key'] = $sessiondata['autologinid']; } ## ##----------[ FIND ]------------------------------------- ## global $db, $userdata; ## ##----------[ REPLACE WITH ]----------------------------- ## global $db, $userdata, $board_config; ## ##----------[ FIND ]------------------------------------- ## $sessiondata['autologinid'] = $autologin_id; ## ##----------[ REPLACE WITH ]----------------------------- ## $sessiondata['autologinid'] = $auto_login_key; ## ##----------[ OPEN ]------------------------------------- ## includes/usercp_avatar.php ## ##----------[ FIND ]------------------------------------- ## if ( $avatar_mode == 'remote' && preg_match('/^(http:\/\/)?([\w\-\.]+)\:?([0-9]*)\/(.*)$/', $avatar_filename, $url_ary) ) ## ##----------[ REPLACE WITH ]----------------------------- ## if ( $avatar_mode == 'remote' && preg_match('/^(http:\/\/)?([\w\-\.]+)\:?([0-9]*)\/([^ \?&=\#\"\n\r\t<]*?(\.(jpg|jpeg|gif|png)))$/', $avatar_filename, $url_ary) ) ## ##----------[ OPEN ]------------------------------------- ## ## Unless you've installed a hack that altered this file, it'll be quicker to ## just replace it with a fresh copy from the 2.0.21 download. ## includes/usercp_confirm.php ## ##----------[ FIND ]------------------------------------- ## // If we can we will generate a single filtered png else we will have to simply // output six seperate original pngs ... first way is preferable! if (@extension_loaded('zlib')) { $_png = define_filtered_pngs(); $total_width = 320; $total_height = 50; $img_height = 40; $img_width = 0; $l = 0; list($usec, $sec) = explode(' ', microtime()); mt_srand($sec * $usec); $char_widths = array(); for ($i = 0; $i < strlen($code); $i++) { $char = $code{$i}; $width = mt_rand(0, 4); $char_widths[] = $width; $img_width += $_png[$char]['width'] - $width; } $offset_x = mt_rand(0, $total_width - $img_width); $offset_y = mt_rand(0, $total_height - $img_height); $image = ''; $hold_chars = array(); for ($i = 0; $i < $total_height; $i++) { $image .= chr(0); if ($i > $offset_y && $i < $offset_y + $img_height) { $j = 0; for ($k = 0; $k < $offset_x; $k++) { $image .= chr(mt_rand(140, 255)); } for ($k = 0; $k < strlen($code); $k++) { $char = $code{$k}; if (empty($hold_chars[$char])) { $hold_chars[$char] = explode("\n", chunk_split(base64_decode($_png[$char]['data']), $_png[$char]['width'] + 1, "\n")); } $image .= randomise(substr($hold_chars[$char][$l], 1), $char_widths[$j]); $j++; } for ($k = $offset_x + $img_width; $k < $total_width; $k++) { $image .= chr(mt_rand(140, 255)); } $l++; } else { for ($k = 0; $k < $total_width; $k++) { $image .= chr(mt_rand(140, 255)); } } } unset($hold); $image = create_png(gzcompress($image), $total_width, $total_height); // Output image header('Content-Type: image/png'); header('Cache-control: no-cache, no-store'); echo $image; unset($image); unset($_png); exit; } else { $_png = define_raw_pngs(); $c = intval($HTTP_GET_VARS['c']); $char = substr($code, $c - 1, 1); header('Content-Type: image/png'); header('Cache-control: no-cache, no-store'); echo base64_decode($_png[$char]); unset($_png); exit; } ## ##----------[ REPLACE WITH ]----------------------------- ## // We can we will generate a single filtered png // Thanks to DavidMJ for emulating zlib within the code :) $_png = define_filtered_pngs(); $total_width = 320; $total_height = 50; $img_height = 40; $img_width = 0; $l = 0; list($usec, $sec) = explode(' ', microtime()); mt_srand($sec * $usec); $char_widths = array(); for ($i = 0; $i < strlen($code); $i++) { $char = $code{$i}; $width = mt_rand(0, 4); $char_widths[] = $width; $img_width += $_png[$char]['width'] - $width; } $offset_x = mt_rand(0, $total_width - $img_width); $offset_y = mt_rand(0, $total_height - $img_height); $image = ''; $hold_chars = array(); for ($i = 0; $i < $total_height; $i++) { $image .= chr(0); if ($i > $offset_y && $i < $offset_y + $img_height) { $j = 0; for ($k = 0; $k < $offset_x; $k++) { $image .= chr(mt_rand(140, 255)); } for ($k = 0; $k < strlen($code); $k++) { $char = $code{$k}; if (empty($hold_chars[$char])) { $hold_chars[$char] = explode("\n", chunk_split(base64_decode($_png[$char]['data']), $_png[$char]['width'] + 1, "\n")); } $image .= randomise(substr($hold_chars[$char][$l], 1), $char_widths[$j]); $j++; } for ($k = $offset_x + $img_width; $k < $total_width; $k++) { $image .= chr(mt_rand(140, 255)); } $l++; } else { for ($k = 0; $k < $total_width; $k++) { $image .= chr(mt_rand(140, 255)); } } } unset($hold); $image = create_png($image, $total_width, $total_height); // Output image header('Content-Type: image/png'); header('Cache-control: no-cache, no-store'); echo $image; unset($image); unset($_png); exit; ## ##----------[ FIND ]------------------------------------- ## function create_png($gzimage, $width, $height) ## ##----------[ REPLACE WITH ]----------------------------- ## function create_png($raw_image, $width, $height) ## ##----------[ FIND ]------------------------------------- ## // IDAT $image .= png_chunk(strlen($gzimage), 'IDAT', $gzimage); ## ##----------[ REPLACE WITH ]----------------------------- ## if (@extension_loaded('zlib')) { $raw_image = gzcompress($raw_image); $length = strlen($raw_image); } else { // The total length of this image, uncompressed, is just a calculation of pixels $length = ($width + 1) * $height; // Adler-32 hash generation // Optimized Adler-32 loop ported from the GNU Classpath project $temp_length = $length; $s1 = 1; $s2 = $index = 0; while ($temp_length > 0) { // We can defer the modulo operation: // s1 maximally grows from 65521 to 65521 + 255 * 3800 // s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31 $substract_value = ($temp_length < 3800) ? $temp_length : 3800; $temp_length -= $substract_value; while (--$substract_value >= 0) { $s1 += ord($raw_image[$index]); $s2 += $s1; $index++; } $s1 %= 65521; $s2 %= 65521; } $adler_hash = pack('N', ($s2 << 16) | $s1); // This is the same thing as gzcompress($raw_image, 0) but does not need zlib $raw_image = pack('C3v2', 0x78, 0x01, 0x01, $length, ~$length) . $raw_image . $adler_hash; // The Zlib header + Adler hash make us add on 11 $length += 11; } // IDAT $image .= png_chunk($length, 'IDAT', $raw_image); ## ##----------[ OPEN ]------------------------------------- ## includes/usercp_register.php ## ##----------[ FIND ]------------------------------------- ## $code = strtoupper(str_replace('0', 'o', substr($code, 6))); ## ##----------[ REPLACE WITH ]----------------------------- ## $code = substr(str_replace('0', 'Z', strtoupper(base_convert($code, 16, 35))), 2, 6); ## ##----------[ FIND ]------------------------------------- ## $confirm_image = (@extension_loaded('zlib')) ? '' : ''; ## ##----------[ REPLACE WITH ]----------------------------- ## $confirm_image = ''; ## ##----------[ SAVE AND CLOSE ALL FILES ]----------------- ## ## End ##