php随机数(php随机数组)

原创Fazx和田智汇1.介绍西湖剑杯线上资格赛线上赌场上,明文攻击的提示给出了/flag/seed.txt和一个字符串代码。在这里,你需要稍微想一想,seed指

原创Fazx和田智汇

1.介绍

西湖剑杯线上资格赛线上赌场上,明文攻击的提示给出了/flag/seed.txt和一个字符串代码。在这里,你需要稍微想一想,seed指的是随机数种子,网页上的代码值是每小时都在变化的“随机数”:

PHP中的随机数安全问题

我们可以用phpmtseed工具(用C写的,速度很快)根据它们撞出随机数的种子,从而得到flag:

PHP中的随机数安全问题

以下是原理分析:

2.随机数的安全缺陷

随机数广泛用于生成验证码、令牌、密钥等场景,可分为真随机数和伪随机数。算法(常用线性同余)和种子(常用时钟)得到的随机数是伪随机的:当种子或生成的随机数已知时,可以预测出随机数序列。

PHP中的随机数安全问题

可以看出,PHP手册实际上是在提示生成随机数进行加密是不安全的,但这种告诫不知何故只存在于英文版的PHP手册中,中文版被省略了...这可能也是很多国内开发应用出现这种缺陷的一个原因。

PHP中的随机数生成函数是rand()和mtrand(),分别对应srand()和mtstrand(),用来种子随机数。我们设置rand.php进行测试:

<?phpmt_srand(2333);srand(2333);echo "seed=2333,rand()产生的随机数序列:\n";for($i=1;$i<=3;$i++){ echo rand()."\n";}echo "seed=2333,mt_rand()产生的随机数序列:\n";for($i=1;$i<=3;$i++){ echo mt_rand()."\n";}?>

执行:

PHP中的随机数安全问题

可以看出,当随机数种子相同时,rand()或mtrand()生成的随机数序列是相同的,种子的泄漏会导致随机数序列的泄漏。当种子值固定时,比如mtsrand(1000),随机数就没用了;并且使用动态种子可能不安全,例如:

//seed值较小,直接遍历爆破mt_srand(mt_rand(0,1000));//用公开的time()作为种子,和静态种子一样危险mt_srand(time());//破解时要注意服务器时间可能存在偏差,需要设定一个较小的范围

从PHP 4.2.0开始,随机数生成器会自动完成播种,不再需要手动调用srand()或mt_srand(),但还是不安全。我们将分别讨论这两个函数。

3、兰德()

Rand()在生成随机数时不会自动调用srand(),生成的随机数序列可以用这个公式预测:

状态[i] =状态[i-3] +状态[i-31]

所以我们可以收集rand()产生的32位以上的随机序列来预测后面的随机序列。

详细参考:破解-Php-Rand

(http://www . sjoerdlangkemper . nl/2016/02/11/cracking-PHP-rand/)

而且在某些平台,rand()的最大值是32767,非常容易被爆。

4、mt_rand()

根据PHP手册,mtrand()生成随机数的速度是libc提供的rand()的4倍。rand()函数默认使用libc随机数生成器,非正式使用mtrand()函数代替。

mtrand()函数的主要安全缺陷是,所谓的“自动播种”实际上是指PHP在同一个请求过程中只会播种一次,也就是说,即使多次调用mtrand()函数,也只会根据第一个播种的种子生成随机数。这个结论的证明可以通过分析mt_rand()的源代码或者写一个小的脚本测试来完成,不展开。该功能的核心实现代码是这部分:

PHPAPI void php_mt_srand(uint32_t seed){ /* Seed the generator with a simple uint32 */ php_mt_initialize(seed, BG(state)); php_mt_reload(); /* Seed only once */ BG(mt_rand_is_seeded) = 1;}/* }}} *//* {{{ php_mt_rand */PHPAPI uint32_t php_mt_rand(void){ /* Pull a 32-bit integer from the generator state Every other access function simply transforms the numbers extracted here */ register uint32_t s1; if (UNEXPECTED(!BG(mt_rand_is_seeded))) { php_mt_srand(GENERATE_SEED()); } if (BG(left) == 0) { php_mt_reload(); } --BG(left); s1 = *BG(next)++; s1 ^= (s1 >> 11); s1 ^= (s1 << 7) & 0x9d2c5680U; s1 ^= (s1 << 15) & 0xefc60000U; return ( s1 ^ (s1 >> 18) );}

因为由种子生成随机数序列的计算是不可逆的,所以有效的破解方法应该是耗尽种子,生成随机数序列,与已知的随机数(序列)进行比较。这也是文章开头提到的phpmtseed工具的实现逻辑。

5.安全建议

当涉及加密/许可/CSRF令牌等敏感操作时:

不要使用时间函数作为种子或直接作为随机数:time()/microtime()不要直接使用rand()``mt_rand()这样的弱伪随机数生成器随机数要足够长以防御暴力破解

6.学习相关话题。

0 CTF 2016 rand 2:http://www.vuln.cn/6004

NJCTF 2017猜想:

https://www.cnblogs.com/afanti/p/8722760.html

7.相关操作培训

PHP常见的危险函数:了解PHP常见的危险函数,以及使用这些函数可能导致的程序漏洞;

PHP中的随机数安全问题

参考:http://wonderkun.cc/index.html/? p = 585

本文为和田原创,未经允许严禁转载。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。

作者:美站资讯,如若转载,请注明出处:https://www.meizw.com/n/171571.html

发表回复

登录后才能评论