10-03-2012, 10:38 AM
Awesome, so I've been doing what you recommended epixoip:
- this went by quick no results
- this went by quick no results
- this took well over 48 hours with 6.43 Trillion progress. No results.
I'm continuing down the list.
About MyBB 1.6.8 .. I'm going to paste the password related PHP source code for you:
(skip to bottom for summary)
in functions.php
in functions_archive.php
in functions_user.php
the above repeats for same files in inc sub directory.
SO to highlight what's important:
Summary
So this is what happens:
md5(md5($salt).$password)
As far as I can tell things have definitely changed from the MyBB 1.2 days... I think the above proves that. That's why I was choosing option 6.
But am I wasting my time with 2811 on plus then? If 2811 = md5(md5(salt).md5(pass)) then maybe I am?
Code:
cudaHashcat -m 2811 -o recovered.txt hashes.txt wordlist.dic
Code:
cudaHashcat -m 2811 -o recovered.txt hashes.txt wordlist.dic -r rules/best64.rule
Code:
cudaHashcat -m 2811 -o recovered.txt hashes.txt wordlist.dic -r rules/d3ad0ne.rule
I'm continuing down the list.
About MyBB 1.6.8 .. I'm going to paste the password related PHP source code for you:
(skip to bottom for summary)
in functions.php
PHP Code:
Starting at line 1319
// Loop through each of parent forums to ensure we have a password for them too
$parents = explode(',', $forum_cache[$fid]['parentlist']);
rsort($parents);
if(!empty($parents))
{
foreach($parents as $parent_id)
{
if($parent_id == $fid || $parent_id == $pid)
{
continue;
}
if($forum_cache[$parent_id]['password'] != "")
{
check_forum_password($parent_id, $fid);
}
}
}
$password = $forum_cache[$fid]['password'];
if($password)
{
if($mybb->input['pwverify'] && $pid == 0)
{
if($password == $mybb->input['pwverify'])
{
my_setcookie("forumpass[$fid]", md5($mybb->user['uid'].$mybb->input['pwverify']), null, true);
$showform = false;
}
else
{
eval("\$pwnote = \"".$templates->get("forumdisplay_password_wrongpass")."\";");
$showform = true;
}
}
else
{
if(!$mybb->cookies['forumpass'][$fid] || ($mybb->cookies['forumpass'][$fid] && md5($mybb->user['uid'].$password) != $mybb->cookies['forumpass'][$fid]))
{
$showform = true;
}
else
{
$showform = false;
}
}
}
else
{
$showform = false;
}
if($showform)
{
if($pid)
{
header("Location: ".$mybb->settings['bburl']."/".get_forum_link($fid));
}
else
{
$_SERVER['REQUEST_URI'] = htmlspecialchars_uni($_SERVER['REQUEST_URI']);
eval("\$pwform = \"".$templates->get("forumdisplay_password")."\";");
output_page($pwform);
}
exit;
}
}
then starting again at line 3071
/**
* Get a list of the unviewable forums for the current user
*
* @param boolean Set to true to only fetch those forums for which users can actually read a thread in.
* @return string Comma separated values list of the forum IDs which the user cannot view
*/
function get_unviewable_forums($only_readable_threads=false)
{
global $forum_cache, $permissioncache, $mybb, $unviewableforums, $unviewable, $templates, $forumpass;
$pid = intval($pid);
if(!$permissions)
{
$permissions = $mybb->usergroup;
}
if(!is_array($forum_cache))
{
cache_forums();
}
if(!is_array($permissioncache))
{
$permissioncache = forum_permissions();
}
$password_forums = array();
foreach($forum_cache as $fid => $forum)
{
if($permissioncache[$forum['fid']])
{
$perms = $permissioncache[$forum['fid']];
}
else
{
$perms = $mybb->usergroup;
}
$pwverified = 1;
if($forum['password'] != "")
{
if($mybb->cookies['forumpass'][$forum['fid']] != md5($mybb->user['uid'].$forum['password']))
{
$pwverified = 0;
}
$password_forums[$forum['fid']] = $forum['password'];
}
else
{
// Check parents for passwords
$parents = explode(",", $forum['parentlist']);
foreach($parents as $parent)
{
if(isset($password_forums[$parent]) && $mybb->cookies['forumpass'][$parent] != md5($mybb->user['uid'].$password_forums[$parent]))
{
$pwverified = 0;
}
}
}
if($perms['canview'] == 0 || $pwverified == 0 || ($only_readable_threads == true && $perms['canviewthreads'] == 0))
{
if($unviewableforums)
{
$unviewableforums .= ",";
}
$unviewableforums .= "'".$forum['fid']."'";
}
}
return $unviewableforums;
}
in functions_archive.php
PHP Code:
starting at line 238
// Loop through each of parent forums to ensure we have a password for them too
$parents = explode(',', $forum_cache[$fid]['parentlist']);
rsort($parents);
if(!empty($parents))
{
foreach($parents as $parent_id)
{
if($parent_id == $fid || $parent_id == $pid)
{
continue;
}
if($forum_cache[$parent_id]['password'] != "")
{
check_forum_password_archive($parent_id, $fid);
}
}
}
$password = $forum_cache[$fid]['password'];
if($password)
{
if(!$mybb->cookies['forumpass'][$fid] || ($mybb->cookies['forumpass'][$fid] && md5($mybb->user['uid'].$password) != $mybb->cookies['forumpass'][$fid]))
{
archive_error_no_permission();
}
}
}
?>
in functions_user.php
PHP Code:
starting at line 175
/**
* Salts a password based on a supplied salt.
*
* @param string The md5()'ed password.
* @param string The salt.
* @return string The password hash.
*/
function salt_password($password, $salt)
{
return md5(md5($salt).$password);
}
/**
* Generates a random salt
*
* @return string The salt.
*/
function generate_salt()
{
return random_str(8);
}
/**
* Generates a 50 character random login key.
*
* @return string The login key.
*/
function generate_loginkey()
{
return random_str(50);
}
/**
* Updates a user's salt in the database (does not update a password).
*
* @param int The uid of the user to update.
* @return string The new salt.
*/
function update_salt($uid)
{
global $db;
$salt = generate_salt();
$sql_array = array(
"salt" => $salt
);
$db->update_query("users", $sql_array, "uid='{$uid}'", 1);
return $salt;
}
/**
* Generates a new login key for a user.
*
* @param int The uid of the user to update.
* @return string The new login key.
*/
function update_loginkey($uid)
{
global $db;
$loginkey = generate_loginkey();
$sql_array = array(
"loginkey" => $loginkey
);
$db->update_query("users", $sql_array, "uid='{$uid}'", 1);
return $loginkey;
}
the above repeats for same files in inc sub directory.
SO to highlight what's important:
PHP Code:
/**
* Updates a user's password.
*
* @param int The user's id.
* @param string The md5()'ed password.
* @param string (Optional) The salt of the user.
* @return array The new password.
*/
function update_password($uid, $password, $salt="")
{
global $db, $plugins;
$newpassword = array();
// If no salt was specified, check in database first, if still doesn't exist, create one
if(!$salt)
{
$query = $db->simple_select("users", "salt", "uid='$uid'", array('limit' => 1));
$user = $db->fetch_array($query);
if($user['salt'])
{
$salt = $user['salt'];
}
else
{
$salt = generate_salt();
}
$newpassword['salt'] = $salt;
}
// Create new password based on salt
$saltedpw = salt_password($password, $salt);
// Generate new login key
$loginkey = generate_loginkey();
// Update password and login key in database
$newpassword['password'] = $saltedpw;
$newpassword['loginkey'] = $loginkey;
$db->update_query("users", $newpassword, "uid='$uid'", 1);
$plugins->run_hooks("password_changed");
return $newpassword;
}
/**
* Salts a password based on a supplied salt.
*
* @param string The md5()'ed password.
* @param string The salt.
* @return string The password hash.
*/
function salt_password($password, $salt)
{
return md5(md5($salt).$password);
}
/**
* Generates a random salt
*
* @return string The salt.
*/
function generate_salt()
{
return random_str(8);
}
/**
* Generates a 50 character random login key.
*
* @return string The login key.
*/
function generate_loginkey()
{
return random_str(50);
}
/**
* Updates a user's salt in the database (does not update a password).
*
* @param int The uid of the user to update.
* @return string The new salt.
*/
function update_salt($uid)
{
global $db;
$salt = generate_salt();
$sql_array = array(
"salt" => $salt
);
$db->update_query("users", $sql_array, "uid='{$uid}'", 1);
return $salt;
}
Summary
So this is what happens:
md5(md5($salt).$password)
As far as I can tell things have definitely changed from the MyBB 1.2 days... I think the above proves that. That's why I was choosing option 6.
But am I wasting my time with 2811 on plus then? If 2811 = md5(md5(salt).md5(pass)) then maybe I am?