浅谈PHP随机数安全的分析 ——燕云实验室

admin 2022年4月16日14:00:50评论55 views字数 3268阅读10分53秒阅读模式


浅谈PHP随机数安全的分析 ——燕云实验室


“燕云实验室”是河北千诚电子科技有限公司成立的网络安全攻防技术研究实验室。主要研究方向为渗透测试、代码审计、逆向分析、漏洞研究、CTF对抗、威胁情报、应急响应等。


浅谈PHP随机数安全的分析 ——燕云实验室

开篇

浅谈PHP随机数安全的分析 ——燕云实验室

之前在身边有很多学PHP的朋友写一些小程序的时候,很多时候会使用PHP随机数函数rand()和mt_rand()函数去生成随机数


可是,随机数真的随机吗?这篇文章讲从多个实例中探讨随机数,当然,有写作不当的地方,还望斧正!


浅谈PHP随机数安全的分析 ——燕云实验室

关于随机函数rand()和mt_rand()

浅谈PHP随机数安全的分析 ——燕云实验室


    rand()和mt_rand()两个函数皆是PHP中生成随机数的函数,可相比之下,mt_rand()的生成速度却是rand()的四倍!在没有参数的情况下,两者生成的数值范围也是不一样的。

echo mt_getrandmax()." and ".getrandmax();

浅谈PHP随机数安全的分析 ——燕云实验室


可以看到页面上的输出,mt_rand()相比较rand()默认取值的范围更大。而且经过测试,在不同的PHP版本中,rand随机数种子相同的时候,随机数却不相同!

浅谈PHP随机数安全的分析 ——燕云实验室


左边web页面使用的是PHP7.0.12,而右边的Powershell却是使用的PHP5.2.17。从上所述,只有mt_rand()所生成的随机数是无版本差异的!

 而这两个生成随机数的时候,是可以通过srand()和mt_srand()设置随机数的种子

<?phpmt_srand(666);srand(666);echo "rand 函数在种子是666时产生的随机数序列:<br/>";for($i=1;$i<5;$i++){   echo rand()."<br/>";}echo '<br/>';echo "mt_rand 函数在种子是666时产生的随机数序列:<br/>";for($i=1;$i<5;$i++){   echo mt_rand()."<br/>";}?>

运行如下图所示

浅谈PHP随机数安全的分析 ——燕云实验室

当你发现,设置的种子为666的时候,不管你刷新多少次,页面中生成的随机数值都不会变!

浅谈PHP随机数安全的分析 ——燕云实验室

所以,当种子泄露的时候,随机数的安全就不堪一击了。


可有什么方法能够得到种子?

    

目前我们唯一能知道的就是随机数是不会变的,而之前有说过mt_srand()生成的随机数范围在0-2147483647之间,我们就可以通过最普通的爆破方式

    

去获取随机数的种子,这里推荐使用php_mt_seed,

项目地址:http://www.openwall.com/php_mt_seed/

    

这里踩到个坑,生成后的随机数分为PHP7.x版本的和5.x版本,具体原因还不知道,但是在php7.x版本以上,mt_srand()函数定义的种子将不能超过int,也就是2147483647,但可以等于该值

浅谈PHP随机数安全的分析 ——燕云实验室


所以,为了更好的研究,下面将会使用PHP5.2.17的版本

首先通过mt_rand()创建一个随机数,然后利用脚本爆破

php -r "echo mt_rand();"

浅谈PHP随机数安全的分析 ——燕云实验室

爆破出来的种子所生成的随机数正好是一样的

那么,页面只播种一次,生成的多个随机数也会一样吗

浅谈PHP随机数安全的分析 ——燕云实验室

事实证明,一次播种,全页不愁。

   竟然已经了解了随机数的相关安全性,下面就放上一些CTF中,或者在某个CMS中出现的有关随机数的审计



浅谈PHP随机数安全的分析 ——燕云实验室

审计案例①(mt_rand()安全性)

浅谈PHP随机数安全的分析 ——燕云实验室


此案例是出自第三届陕西网络空间安全技术大赛

<?phperror_reporting(0);function cpassword($pw_length = 10){    $randpwd = "";    for ($i = 0; $i < $pw_length; $i++)    {        $randpwd .= chr(mt_rand(33, 126));    }    return $randpwd;}
session_start();mt_srand(time());$pwd=cpassword(10);if($pwd === $_GET['pwd']){ echo "Good job, you get the key is:".$pwd;}else{ echo "Wrong!";}
$_SESSION['userLogin']=cpassword(32).rand();?>


从给出的代码中可以看到

$pwd=cpassword(10);

程序通过时间戳播种,然后通过cpassword建立一个密码,并验证密码是否正确,否则就输出flag


通过之前研究发现mt_rand()生成的随机数是有固定的,只需要知道mt_srand(time());的结果行了


写个脚本,直接用time函数生成的时间戳设置种子,再发送数据内容过去,就能获取到flag


脚本如下

<?phpfunction do_get($url, $params) {    $url = "{$url}?" . http_build_query ( $params );    $ch = curl_init ();    curl_setopt ( $ch, CURLOPT_URL, $url );    curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );    curl_setopt ( $ch, CURLOPT_CUSTOMREQUEST, 'GET' );    curl_setopt ( $ch, CURLOPT_TIMEOUT, 60 );    curl_setopt ( $ch, CURLOPT_POSTFIELDS, $params );    $result = curl_exec ( $ch );    curl_close ( $ch );    return $result;}
function cpassword($pw_length = 10){ $randpwd = ""; for ($i = 0; $i < $pw_length; $i++) { $randpwd .= chr(mt_rand(33, 126)); } return $randpwd;}
mt_srand(time());$pwd=cpassword(10);echo 'send:'.$pwd.'<br/>';$url="http://localhost/index.php";$params=array('pwd'=>$pwd);$result=do_get($url,$params);echo 'result:'.json_encode($result);?>

浅谈PHP随机数安全的分析 ——燕云实验室

发送的密码与服务器所生成的密码是一样的!

假如按照刚才的生成密码的函数

function cpassword($pw_length = 10){    $randpwd = "";    for ($i = 0; $i < $pw_length; $i++)    {        $randpwd .= chr(mt_rand(33, 126));    }    return $randpwd;}

 这次给出生成后的密码,现在怎样才能得到mt_srand()设置的种子

浅谈PHP随机数安全的分析 ——燕云实验室


生成的密码:

{|M}2x0:kW

 按照程序执行流程,应该先得到每个字符在chr(33)~chr(126)中的位置索引

<?php $str = "!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~"; $ss = "{|M}2x0:kW"; for($i=0;$i<strlen($ss);$i++){    $pos = strpos($str,$ss[$i]);    echo $pos." ".$pos." "."0 ".(strlen($str)-1)." ";    //整理成方便 php_mt_seed 测试的格式   //php_mt_seed VALUE_OR_MATCH_MIN [MATCH_MAX [RANGE_MIN RANGE_MAX]] }?>

 通过这个脚本换成方便php_mt_seed测试的格式

浅谈PHP随机数安全的分析 ——燕云实验室

90 90 0 93 91 91 0 93 44 44 0 93 92 92 0 93 17 17 0 93 87 87 0 93 15 15 0 93 25 25 0 93 74 74 0 93 54 54 0 93

 最终得到种子数1555747516

浅谈PHP随机数安全的分析 ——燕云实验室

浅谈PHP随机数安全的分析 ——燕云实验室





浅谈PHP随机数安全的分析 ——燕云实验室

扫描二维码获取

更多精彩

浅谈PHP随机数安全的分析 ——燕云实验室
浅谈PHP随机数安全的分析 ——燕云实验室

燕云实验室

浅谈PHP随机数安全的分析 ——燕云实验室
浅谈PHP随机数安全的分析 ——燕云实验室


原文始发于微信公众号(燕云实验室):浅谈PHP随机数安全的分析 ——燕云实验室

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年4月16日14:00:50
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   浅谈PHP随机数安全的分析 ——燕云实验室http://cn-sec.com/archives/918426.html

发表评论

匿名网友 填写信息