千家信息网

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

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,**说到随机函数的应用,作为一个菜鸟,理解的也不是很深刻,在这里之作为一个笔记来记录,以后慢慢将其掌握之后,再在内容上面进行加深。随机函数的作用,常常是用来生成验证码、随机文件名、订单号,如果用来做安
千家信息网最后更新 2026年10月31日php随机函数mt_rand()产生的小问题大漏洞

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

随机函数的作用,常常是用来生成验证码、随机文件名、订单号,如果用来做安全验证的话常常用来生成加密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()函数都需要生成一个随机种子的话,那根本就没办法破解。
做一个简单的测试,测试随机数种子相同,后面的每次执行的随机数也相同
脚本:

";echo mt_rand()."
";echo mt_rand()."
";echo mt_rand()."
";echo mt_rand()."
";echo mt_rand()."
";echo mt_rand()."
";echo mt_rand()."
";echo mt_rand()."
";?>


两次执行结果:

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

--
接下来就来验证一下
首先爆破出随机数种子,利用工具php_mt_srand
工具链接:https://github.com/lepiaf/php_mt_seed
这个工具的具体用法,也不再着解释,说起来还是挺复杂的,在这里推荐一个文章吧,看完就看一了解个大概,同时还有助于理解随机数

https://×××w.openwall.com/php_mt_seed/README
爆破随机数种子,我们将得到的第一组数进行爆破

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

--
如何验证?
1、只需要将这个种子通过mt_srand()函数生成数值后再调用几组mt_rand()函数生成几组随机数\
2、然后将随机数和我们刚开始得到的随机数对比即可。
测试第一组


测试第二组


测试第三组


可以看到只有第二组的随机数和原来的相同,到这里便成功获取到了seed值。

三、CTF中的题目

题目来自于成都大学网络***演练平台--随机数
题目链接:http://ctf.cdusec.org/challenges
题目非常简单,直接就给出了题目随机数的源码以及前几组随机数:

";echo mt_rand()."
";echo mt_rand()."
";echo mt_rand()."
";echo mt_rand()."
";echo mt_rand()."
";echo mt_rand()."
";echo mt_rand()."
";echo mt_rand()."
";echo mt_rand()."
";echo "echo flag{".mt_rand()."}"?>9844897526193871232070958802210555936819094738661679323715191033216864056964611030016951871111424flagSo, Please guess the flag!

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

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

四、应当注意的问题。

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

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

相关链接:
http://php.net/manual/en/function.mt-rand.php
http://php.net/manual/zh/function.mt-rand.php

函数 生成 随机数 种子 问题 相同 数值 题目 测试 爆破 安全 验证 之间 同时 时候 版本 不同 接下来 只有 工具 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网是第几次科技革命的成果 广州大一互联网络科技有限公司 中关村互联网 科技集团 互联网科技工作委员会副主任毛军 广州互联网科技公司 互联网科技论坛 长亮科技互联网金融 互联网高科技股票 盛创互联网科技有限公司 互联网科技博主是什么意思 中国科技互联网公司收入 广州市恰铎互联网科技有限公司 链环科技传统企业怎么转型互联网 互联网金融科技公司的优势 昆明中奇联合互联网科技 云鲸互联网络科技有限公司 互联网公司属于科技吗 云南互联网科技学费 绵阳真晨互联网科技有限公司 优雇互联网科技有限公司 广州紫鲸互联网科技有限公司 互联网科技公司电话 汇久创客互联网科技 互联网科技汛 广州市恰铎互联网科技有限公司 上海京穆互联网科技有限公司 互联网科技资金流入 互联网领先科技宣传片 上海同邻互联网科技有限公司规模 互联网科技收购价值
0