内容简介:**说到随机函数的应用,作为一个菜鸟,理解的也不是很深刻,在这里之作为一个笔记来记录,以后慢慢将其掌握之后,再在内容上面进行加深。随机函数的作用,常常是用来生成验证码、随机文件名、订单号,如果用来做安全验证的话常常用来生成加密key、token等等。**--
**说到随机函数的应用,作为一个菜鸟,理解的也不是很深刻,在这里之作为一个笔记来记录,以后慢慢将其掌握之后,再在内容上面进行加深。
随机函数的作用,常常是用来生成验证码、随机文件名、订单号,如果用来做安全验证的话常常用来生成加密key、token等等。**
一、常见的随机函数
常用的随机函数,默认生成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/>"; ?>
两次执行结果:
可以看到得到的随机数是相同的。
同时我们应该注意,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
题目非常简单,直接就给出了题目随机数的源码以及前几组随机数:
<?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()函数的时候才会自动播种,接下来的就会根据这个种子生成随机数。所以我们来利用第一组爆破
2、将seed数值带入到脚本mt_srand()函数当中,去跑flag,因为只要得到seed,接下来不管怎么跑,跑几次,得到的几组数值都是相同的。这里得到两组seed值,测试两次,将得到的flag递交看一下那个正确即可。
四、应当注意的问题。
随机数这个东西在系统之间和 php 版本之间是有削微的区别的,比如就CTF这道题目而言,开始我并没有注意php版本问题,当时的测试环境是php7的版本,同样的做法,答案却是不同的,所以结果也一直出不来。
同时也告诉我们,细节决定成败。
因为是刚刚学习这一知识点,可能讲解的也不够详细或者有些许错误。哪位大佬看到不准确的希望给指出,谢谢!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Parity多重签名函数库自杀漏洞
- 漏洞分析连载第十四期 | 拘于小节的调用权限,函数调用权限漏洞
- 拒绝超长函数,从两个curl远程漏洞说起
- 拒绝超长函数,从两个curl远程漏洞说起
- 代码审计Day12 – 误用htmlentities函数引发的漏洞
- CVE-2018-19518:PHP imap_open函数任意命令执行漏洞复现
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
父与子的编程之旅
桑德 (Warren Sande)、桑德 (Carter Sande) / 苏金国、易郑超 / 人民邮电出版社 / 2014-10-1 / CNY 69.00
本书是一本家长与孩子共同学习编程的入门书。作者是一对父子,他们以Python语言为例,详尽细致地介绍了Python如何安装、字符串和操作符等程序设计的基本概念,介绍了条件语句、函数、模块等进阶内容,最后讲解了用Python实现游戏编程。书中的语言生动活泼,叙述简单明了。 为了让学习者觉得编程有趣,本书编排了很多卡通人物及场景对话,让学习者在轻松愉快之中跨入计算机编程的大门。 第 2 版新增内......一起来看看 《父与子的编程之旅》 这本书的介绍吧!