Trouble with Custom Script
So...I decided to improve on the default passwordcheck.php in the admincp. Rather then just checking to see if my users passwords are just their username, I decided to modify it to use an array that I've filled with the top 25 most commonly used passwords.
And it works! Kind of. It tells you the correct number of users (I assume) that meet the check criteria, however, for some reason when you reset those users passwords, the script continues past the number of people that it says have the vulnerable passwords and keeps climbing up and up, resetting passwords until I stop it.
Anyone feel up for helping?
PHP Code:
<?php
/*======================================================================*\
|| #################################################################### ||
|| # vBulletin 4.2.3 - Licence Number VBC63C2FFA
|| # ---------------------------------------------------------------- # ||
|| # Copyright ?2000-2015 vBulletin Solutions Inc. All Rights Reserved. ||
|| # This file may not be redistributed in whole or significant part. # ||
|| # ---------------- VBULLETIN IS NOT FREE SOFTWARE ---------------- # ||
|| # http://www.vbulletin.com | http://www.vbulletin.com/license.html # ||
|| #################################################################### ||
\*======================================================================*/
// ######################## SET PHP ENVIRONMENT ###########################
error_reporting(E_ALL & ~E_NOTICE);
// ##################### DEFINE IMPORTANT CONSTANTS #######################
define('CVS_REVISION', '$RCSfile$ - $Revision: 25957 $');
// #################### PRE-CACHE TEMPLATES AND DATA ######################
$phrasegroups = array('maintenance');
$specialtemplates = array();
// ########################## REQUIRE BACK-END ############################
require_once('./global.php');
require_once(DIR . '/includes/functions_file.php');
require_once(DIR . '/includes/functions_login.php');
require_once(DIR . '/includes/functions_misc.php');
/*************************************/
/* 25 Most Commonly Used Passwords */
/*************************************/
$badPassword = array(
"baseball", //0
"1234567", //1
"welcome", //2
"1234567890", //3
"abc123", //4
"123456", //5
"password", //6
"12345678", //7
"qwerty", //8
"12345", //9
"123456789", //10
"football", //11
"1234", //12
"111111", //13
"1qaz2wsx", //14
"dragon", //15
"master", //16
"monkey", //17
"letmein", //18
"login", //19
"princess", //20
"qwertyuiop", //21
"solo", //22
"passw0rd", //23
"starwars" //24
);
// ######################## CHECK ADMIN PERMISSIONS #######################
if (!can_administer('canadminusers'))
{
print_cp_no_permission();
}
// ############################# LOG ACTION ###############################
log_admin_action();
// ########################################################################
// ######################### START MAIN SCRIPT ############################
// ########################################################################
print_cp_header($vbphrase['check_vulnerable_passwords']);
if (empty($_REQUEST['do']))
{
$_REQUEST['do'] = ($_POST['doreset'] ? 'reset' : 'check');
}
// checkable periods
$periods = array(
'0' => $vbphrase['over_any_period'],
'259200' => construct_phrase($vbphrase['over_x_days_ago'], 3),
'604800' => $vbphrase['over_1_week_ago'],
'1209600' => construct_phrase($vbphrase['over_x_weeks_ago'], 2),
'1814400' => construct_phrase($vbphrase['over_x_weeks_ago'], 3),
'2592000' => $vbphrase['over_1_month_ago'],
'5270400' => construct_phrase($vbphrase['over_x_months_ago'], 2),
'7862400' => construct_phrase($vbphrase['over_x_months_ago'], 3),
'15724800' => construct_phrase($vbphrase['over_x_months_ago'], 6)
);
// get language information
$languages = array(0 => '');
$languages = array_merge($languages, fetch_language_titles_array('', 0));
// input
$vbulletin->input->clean_array_gpc('p', array(
'period' => TYPE_UINT,
'quantity' => TYPE_UINT,
'email' => TYPE_NOHTML,
'email_subject' => TYPE_NOHTML,
'email_from' => TYPE_NOHTML,
'languageid' => TYPE_UINT
));
// selected period
$period = $vbulletin->GPC['period'];
// count affected accounts
$total_affected = $vbulletin->db->query_first("
SELECT COUNT(userid) AS total_affected
FROM " . TABLE_PREFIX . "user
WHERE password = MD5(CONCAT(MD5(username),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[0] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[1] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[2] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[3] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[4] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[5] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[6] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[7] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[8] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[9] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[10] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[11] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[12] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[13] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[14] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[15] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[16] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[17] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[18] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[19] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[20] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[21] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[22] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[23] . "'),salt)) OR password = MD5(CONCAT(MD5('" . $badPassword[24] . "'),salt)) " .
($period ? 'AND lastvisit < ' . (TIMENOW - $period) : '') . "
");
$total_affected = (!empty($total_affected) ? $total_affected['total_affected'] : 0);
// ########################################################################
if ($_POST['do'] == 'reset')
{
$vbulletin->input->clean_array_gpc('p', array(
'lastuser' => TYPE_UINT,
'reset' => TYPE_UINT,
'processed' => TYPE_UINT,
'email_errors' => TYPE_BOOL,
'reset_errors' => TYPE_BOOL,
'reset_on_error'=> TYPE_BOOL,
'do_banned' => TYPE_UINT
));
$lastuser = $vbulletin->GPC['lastuser'];
$reset = $vbulletin->GPC['reset'];
$processed = $vbulletin->GPC['processed'];
$reset_errors = $vbulletin->GPC['reset_errors'];
$email_errors = $vbulletin->GPC['email_errors'];
$reset_on_error = $vbulletin->GPC['reset_on_error'];
$do_banned = $vbulletin->GPC['do_banned'];
$languageid = $vbulletin->GPC['languageid'];
if (empty($vbulletin->GPC['email_subject']) OR empty($vbulletin->GPC['email']) OR empty($vbulletin->GPC['email_from']))
{
print_stop_message('please_complete_required_fields');
}
if (false === strpos($vbulletin->GPC['email'], '{password}'))
{
print_stop_message('you_must_enter_the_password_token_into_the_message');
}
// select affected users
$result = $vbulletin->db->query("
SELECT user.userid, userban.liftdate
FROM " . TABLE_PREFIX . "user AS user
LEFT JOIN " . TABLE_PREFIX . "userban AS userban
ON user.userid = userban.userid
WHERE user.password = MD5(CONCAT(MD5(user.username),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[0] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[1] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[2] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[3] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[4] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[5] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[6] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[7] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[8] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[9] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[10] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[11] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[12] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[13] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[14] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[15] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[16] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[17] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[18] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[19] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[20] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[21] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[22] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[23] . "'),user.salt)) OR user.password = MD5(CONCAT(MD5(user.'" . $badPassword[24] . "'),user.salt)) " .
($period ? 'AND user.lastvisit < ' . (TIMENOW - $period) : '') . "
AND user.userid > $lastuser " .
($languageid ? "AND user.languageid = " . $languageid : '') . "
LIMIT 0, " . $vbulletin->GPC['quantity'] . "
");
if ($total = $vbulletin->db->num_rows($result))
{
while ($user = $vbulletin->db->fetch_array($result))
{
// set last user processed
$lastuser = $user['userid'];
// copy the ban liftdate before it is removed by fetch_userinfo
$liftdate = $user['liftdate'];
// fetch their info
$user = fetch_userinfo($user['userid']);
// make random password
$newpassword = fetch_random_password(8);
// send mail to user
if ($do_banned OR ($liftdate !== "0"))
{
$message = str_replace('{username}', $user['username'], $vbulletin->GPC['email']);
$message = str_replace('{password}', $newpassword, $message);
if (!vbmail($user['email'], $vbulletin->GPC['email_subject'], $message, true, $vbulletin->GPC['from']))
{
$email_errors = true;
if (!$reset_on_error)
{
continue;
}
}
}
// reset the password
$userdata = datamanager_init('User', $vbulletin, ERRTYPE_SILENT);
$userdata->set_existing($user);
$userdata->set('password', $newpassword);
$userdata->save();
// check reset for errors
if (sizeof($userdata->errors))
{
$reset_errors = true;
continue;
}
$reset++;
}
$vbulletin->db->free_result($result);
unset($userdata);
$processed = $processed + $total;
$_POST['do'] = 'resetnext';
}
else
{
// display results
print_table_start();
print_table_header($vbphrase['passwords_reset']);
print_description_row(construct_phrase($vbphrase['x_of_y_passwords_were_reset'], $reset, $processed), false, 2, '', 'center');
if ($reset_errors)
{
print_description_row($vbphrase['some_errors_occured_while_resetting_passwords']);
}
if ($email_errors)
{
print_description_row($vbphrase['some_errors_occured_while_sending_emails']);
}
if ($languageid)
{
print_description_row(construct_phrase($vbphrase['only_accounts_using_language_x_were_processed'], $languages[$languageid]));
}
print_table_footer();
// display check form for resubmit
$_REQUEST['do'] = 'check';
}
}
// ########################################################################
if ($_POST['do'] == 'resetnext')
{
print_form_header('passwordcheck', 'reset', false, true, 'cpform_reset');
print_description_row(construct_phrase($vbphrase['x_accounts_processed'], $processed), false, 2, '', 'center');
construct_hidden_code('email_errors', $email_errors);
construct_hidden_code('reset_errors', $reset_errors);
construct_hidden_code('reset_on_error', $reset_on_error);
construct_hidden_code('email', $vbulletin->GPC['email'], false);
construct_hidden_code('email_subject', $vbulletin->GPC['email_subject'], false);
construct_hidden_code('email_from', $vbulletin->GPC['email_from'], false);
construct_hidden_code('quantity', $vbulletin->GPC['quantity']);
construct_hidden_code('reset', $reset);
construct_hidden_code('processed', $processed);
construct_hidden_code('do_banned', $do_banned);
construct_hidden_code('lastuser', $lastuser);
construct_hidden_code('languageid', $languageid);
print_submit_row($vbphrase['continue'], 0);
print_table_footer();
?>
<script type="text/javascript">
<!--
if (document.cpform_reset)
{
function send_submit()
{
var submits = YAHOO.util.Dom.getElementsBy(
function(element) { return (element.type == "submit") },
"input", this
);
var submit_button;
for (var i = 0; i < submits.length; i++)
{
submit_button = submits[i];
submit_button.disabled = true;
setTimeout(function() { submit_button.disabled = false; }, 10000);
}
return false;
}
YAHOO.util.Event.on(document.cpform_reset, 'submit', send_submit);
send_submit.call(document.cpform_reset);
document.cpform_reset.submit();
}
// -->
</script>
<?php
vbflush();
}
// ########################################################################
if ($_REQUEST['do'] == 'check')
{
// postback or default values
$email = construct_phrase(($vbulletin->GPC['email'] ? $vbulletin->GPC['email'] : $vbphrase['vulnerable_password_reset_email']), $vbulletin->options['bbtitle'], $vbulletin->options['bburl']);
$email_subject = construct_phrase(($vbulletin->GPC['email_subject'] ? $vbulletin->GPC['email_subject'] : $vbphrase['vulnerable_password_reset_email_subject']), $vbulletin->options['bbtitle']);
$email_from = ($vbulletin->GPC['email_from'] ? $vbulletin->GPC['email_from'] : $vbulletin->options['webmasteremail']);
$quantity = ($vbulletin->GPC['quantity'] ? $vbulletin->GPC['quantity'] : min($total_affected, 100));
// display notice and check options
print_form_header('passwordcheck', 'check');
print_table_header($vbphrase['check_vulnerable_passwords']);
print_description_row($vbphrase['password_check_notice']);
print_select_row($vbphrase['check_accounts_with_last_activity'], 'period', $periods, $period);
print_description_row('<strong>' . ($period ? construct_phrase($vbphrase['affected_accounts_that_were_last_active_x_y'], strtolower($periods[$period]), $total_affected) : construct_phrase($vbphrase['affected_accounts_x'], $total_affected)) . '</strong>');
construct_hidden_code('email', $email, false);
construct_hidden_code('email_subject', $email_subject, false);
construct_hidden_code('email_from', $email_from, false);
construct_hidden_code('quantity', $quantity);
print_submit_row($vbphrase['check_affected_accounts'], false);
print_table_footer();
// display reset options
print_form_header('passwordcheck', 'reset');
print_table_header($vbphrase['reset_vulnerable_passwords']);
print_column_style_code(array('width: 40%','width: 60%'));
print_select_row($vbphrase['reset_accounts_with_last_activity'], 'period', $periods, $period);
print_input_row($vbphrase['email_to_send_at_once'], 'quantity', $quantity);
print_input_row($vbphrase['email_subject'], 'email_subject', $email_subject, false, 70);
print_input_row($vbphrase['email_from'], 'email_from', $email_from, false, 70);
print_textarea_row($vbphrase['password_vulnerability_email_message_label'], 'email', $email, 30, 70);
print_select_row($vbphrase['reset_passwords_for_users_with_language'], 'languageid', $languages, $languageid);
print_yes_no_row($vbphrase['email_permanently_banned_users'], 'do_banned', 0);
print_yes_no_row($vbphrase['reset_password_if_email_failed'], 'reset_on_error', 0);
print_submit_row($vbphrase['reset_vulnerable_passwords'], false);
print_table_footer();
}
print_cp_footer();
/*======================================================================*\
|| ####################################################################
|| # Downloaded: 14:22, Wed Jun 24th 2015
|| # CVS: $RCSfile$ - $Revision: 25957 $
|| ####################################################################
\*======================================================================*/
|