php随机函数mt_rand()产生的小问题大漏洞

栏目: PHP · 发布时间: 5年前

内容简介:**说到随机函数的应用,作为一个菜鸟,理解的也不是很深刻,在这里之作为一个笔记来记录,以后慢慢将其掌握之后,再在内容上面进行加深。随机函数的作用,常常是用来生成验证码、随机文件名、订单号,如果用来做安全验证的话常常用来生成加密key、token等等。**--

**说到随机函数的应用,作为一个菜鸟,理解的也不是很深刻,在这里之作为一个笔记来记录,以后慢慢将其掌握之后,再在内容上面进行加深。

随机函数的作用,常常是用来生成验证码、随机文件名、订单号,如果用来做安全验证的话常常用来生成加密key、token等等。**

一、常见的随机函数

1、rand()

常用的随机函数,默认生成0-getrandmax()之间的随机数,不过因为性能问题,已经被mt_rand()函数替代

相关函数:

rand(int $min,int $max)

srand(int $seed),生成时间种子,同一个时间种子下随机生成的随机数值是相同的。

getrandmax()获取最大随机数,这里获取的随机数会随系统的不同而不同。如 linux 最大2147483647

2、mt_rand

常用的随机函数,默认生成0-mt_getrandmax()之间的随机数, Mersenne Twister 算法生成随机整数

相关函数:

mt_srand(),生成种子,同一个种子下随机生成的随机数值是相同的。

该函数是产生随机值的更好选择,返回结果的速度是 rand() 函数的 4 倍(手册是是这么写的),我个人并不认同的,我感觉他说的4倍是很多年前的事了。因为mt_rand()使用的Mersenne Twister algorythm是1997的事,所以在很多年前,和rand()在速度上的差异可能是(4倍),自2004年,rand()已经开始使用algorythm,所以现在它们速度上没有太大的区别.

有时候手册也是骗人的,就像一会要说的这个函数造成的问题。

3、uniqid()

生成唯一ID的函数,精确到了微妙,较mt_rand精确。适用场景生成token和生成uuid

具体细节没做研究

4、openssl_random_pseudo_bytes()

适用于生成token,具体详情没做研究

二、mt_rand()函数造成的问题所在

--

今天重点记录一下mt_rand带来的问题,和在CTF中的具体解法。对于这个函数的介绍是有两个版本的,一个是英文版,一个是中文版,去对比一下,在英文版中会多出一个警告:

Caution:This function does not generate cryptographically secure values, and should not be used for cryptographic purposes. If you need a cryptographically secure value, consider using random_int(), random_bytes(), or openssl_random_pseudo_bytes() instead.

意思是注意函数的安全,不能用来生成密码安全值,不要引用于加密,如果需要可以适用等等函数代替。其实函数本身是没有问题的,只是使用的方式不当而已。

我没有挖漏洞的经验,所以也不清楚大佬说的这方面的漏洞多不多,但以我个人而言,肯定只会选择看中文版的介绍,并且使用此函数去生成密码安全值。这样就不知道警告,也就会造成安全问题。

首先我们要知道,每一次调用mt_rand()函数的时候,都会检查一下系统有没有播种。(播种是由mt_srand()函数完成的),当随机种子生成后,后面生成的随机数都会根据这个随机种子生成。所以前面也说到,同一个种子下随机生成的随机数值是相同的。同时,也解释了我们破解随机种子的可行性。如果每次调用mt_rand()函数都需要生成一个随机种子的话,那根本就没办法破解。

做一个简单的测试,测试随机数种子相同,后面的每次执行的随机数也相同

脚本:

<?php
mt_srand(45678913);
echo mt_rand()."<br/>";
echo mt_rand()."<br/>";
echo mt_rand()."<br/>";
echo mt_rand()."<br/>";
echo mt_rand()."<br/>";
echo mt_rand()."<br/>";
echo mt_rand()."<br/>";
echo mt_rand()."<br/>";
echo mt_rand()."<br/>";
?>
php随机函数mt_rand()产生的小问题大漏洞

两次执行结果:

php随机函数mt_rand()产生的小问题大漏洞

可以看到得到的随机数是相同的。

同时我们应该注意,mt_srand()函数播种的时候,只有在第一次调用mt_rand()函数的时候才会使用。所以如果我们知道了第一次生成的随机数值,就可能爆破出随机数种子。

--

接下来就来验证一下

首先爆破出随机数种子,利用工具php_mt_srand

工具链接: https://github.com/lepiaf/php_mt_seed

这个 工具 的具体用法,也不再着解释,说起来还是挺复杂的,在这里推荐一个文章吧,看完就看一了解个大概,同时还有助于理解随机数

https://×××w.openwall.com/php_mt_seed/README

爆破随机数种子,我们将得到的第一组数进行爆破

php随机函数mt_rand()产生的小问题大漏洞

得到三组seed值,里面就有我们使用的随机数种子,当然在正常情况下我们是不知道这个数值的,所以还需要去验证。

--

如何验证?

1、只需要将这个种子通过mt_srand()函数生成数值后再调用几组mt_rand()函数生成几组随机数\

2、然后将随机数和我们刚开始得到的随机数对比即可。

测试第一组

php随机函数mt_rand()产生的小问题大漏洞
php随机函数mt_rand()产生的小问题大漏洞

测试第二组

php随机函数mt_rand()产生的小问题大漏洞
php随机函数mt_rand()产生的小问题大漏洞

测试第三组

php随机函数mt_rand()产生的小问题大漏洞

php随机函数mt_rand()产生的小问题大漏洞 可以看到只有第二组的随机数和原来的相同,到这里便成功获取到了seed值。

三、CTF中的题目

题目来自于成都大学网络***演练平台--随机数

题目链接: http://ctf.cdusec.org/challenges

题目非常简单,直接就给出了题目随机数的源码以及前几组随机数:

<?php
echo "PHP 5.4.26";
mt_srand(xxxxxxxx);
#We can't tell you what is xxxxxxxx!
echo mt_rand()."<br/>";
echo mt_rand()."<br/>";
echo mt_rand()."<br/>";
echo mt_rand()."<br/>";
echo mt_rand()."<br/>";
echo mt_rand()."<br/>";
echo mt_rand()."<br/>";
echo mt_rand()."<br/>";
echo mt_rand()."<br/>";
echo mt_rand()."<br/>";
echo "echo flag{".mt_rand()."}"
?>
984489752
619387123
2070958802
2105559368
1909473866
1679323715
1910332168
640569646
1103001695
1871111424
flag
So, Please guess the flag!

理解了上面所说的爆破步骤的话,对这个题目简直太容易了。

1、因为我们不知道××××代表那些数字,但是给出了第一组随机数。上面也说了,只有第一次调用mt_rand()函数的时候才会自动播种,接下来的就会根据这个种子生成随机数。所以我们来利用第一组爆破

php随机函数mt_rand()产生的小问题大漏洞

2、将seed数值带入到脚本mt_srand()函数当中,去跑flag,因为只要得到seed,接下来不管怎么跑,跑几次,得到的几组数值都是相同的。这里得到两组seed值,测试两次,将得到的flag递交看一下那个正确即可。

php随机函数mt_rand()产生的小问题大漏洞

四、应当注意的问题。

随机数这个东西在系统之间和 php 版本之间是有削微的区别的,比如就CTF这道题目而言,开始我并没有注意php版本问题,当时的测试环境是php7的版本,同样的做法,答案却是不同的,所以结果也一直出不来。

同时也告诉我们,细节决定成败。

因为是刚刚学习这一知识点,可能讲解的也不够详细或者有些许错误。哪位大佬看到不准确的希望给指出,谢谢!


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

知识的边界

知识的边界

[美] 戴维·温伯格 / 胡泳、高美 / 山西人民出版社 / 2014-12-1 / 42.00元

大数据时代反思知识 因为事实不再是事实,专家随处可见 所有确定性都被连根拔起,话题再无边界,没有人对任何事情能达成一致。 在互联网的引领下,知识现在已经具有了社交性,流动且开放。温伯格向我们展示了这些特点如何可以为我们所用。 ——马克•贝尼奥夫(云计算之父,著有《云攻略》) 这本富有洞见的著作,奠定了温伯格作为数字时代最重要的思想家之一的地位。如果你想要理解信息洪流涌......一起来看看 《知识的边界》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器