前言
以前打CTF的时候有问题。 一个关键是预测随机数。 根据上次给定的随机数,预测下一个随机数。 今天看《白帽子》的时候重点看了,顺便记录一下
正文
php中的两个重要随机函数是、
如果未指定rand参数,则范围为0-32767
如果未指定md_rand () /参数,则范围为0-2^32-1
在srand ()//rand )函数中播种
在mt_srand ()//mt_srand ) )函数中播种
php是基于c开发的,在c中生成随机数时,必须自己查找种子。 同一种子生成的随机数相同,在php中也相同
从php 4.2.0开始,不再需要使用srand (或mt_srand )在随机数生成器中种子。 这是因为目前系统自动运行的————来自PHP官方文档
查看以下示例,当向mt_rand函数广播下一个固定值时! [ (3358 blog.kingkk.com/WP-content/uploads/2018/02/FD7DD 919 da 74099 e 400 efcdaef 764 b 77.png ) ]刷新也不一样
因此,在seed恒定的情况下,下一次的随机数是固定的
我记得以前播种问题时取0-99999的随机数播种。 本地测试代码为test.php
$ seed=rand (0,99999 );
echo“seed is :”. $ seed .”
“;
mt_srand($seed;
echo mt_rand ()."
“;
echo mt_rand ()."
“;
echo mt_rand ()."
“;
echo mt_rand ()."
“;
echo mt_rand ()."
“;
echo mt_rand ()."
“;
echo mt_rand ()."
“;
echo mt_rand ()."
“;
?
取1次输出时
我们得到第一个随机数(1240422887 )时,它求出seed,进而预测下一个随机数。 代码为以下1.php
函数get _ seed ($ rand _ num ) {
for($I=0; $i100000; $i ) {
mt_Srand($I;
if(mt_rand(==$rand_num ) {
返回$ I;
}
}
返回假;
}
$rand_num=1240422887;
$seed=get_seed($rand_num );
echo " these edis : ".$ seed."
“;
mt_srand($seed;
echo mt_rand ()."
“;
echo mt_rand ()."
“;
echo mt_rand ()."
“;
echo mt_rand ()."
“;
echo mt_rand ()."
“;
echo mt_rand ()."
“;
echo mt_rand ()."
“;
echo mt_rand ()."
“;
?
这1 .访问PHP
成功求出了播放的seed,还预测了以下值
这里故意缩小了seed的范围,但是php4.2以后,就不需要手动赋值了。 此时,系统给出的seed值范围应该也不长于0-2^32(32位服务器上)爆破时间。 特意测试了一下。 如果我在本地计算机上跑100000的话是0.687s秒,2147483648的话是EMC
以下演示提供了需要test.php和test2.php两个页面的渗透测试的一部分。 test.php用于种子,test2.php用于生成随机数。 访问test.php获取seed,确保种子从头到尾都是一样的,访问时请珍惜keep-alive。 然后,执行模拟业务处理,跳至具体业务处理页面test2.php
mt_srand () double ) microtime ) *1000000 );
header (“location :3358 localhost/code/test2. PHP '”
?
获取了test2.php生成的随机数值
此时,根据以前的函数求出seed,可以预测接下来在不新播种的业务中产生的随机数
请刷新test2.php页面几次并验证
bingo,成功预测了生成的随机数
注意:
要保持keep-alive的连接,如果此过程中断,种子将不是以前的test.php的种子。 我在用福克斯的插件。 添加了keep-alive的头部。 其次,如果以后再种子,如果不是人工播种,应该可以求出其seed。 但是,范围变大,成本高
总结
所谓的随机数是伪随机数,而不是真随机数