PHP 的 rand() 函数是否曾被用作漏洞利用? [英] Was there a a time when PHP's rand() function was used as an exploit?

查看:157
本文介绍了PHP 的 rand() 函数是否曾被用作漏洞利用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人知道是否有人使用rand()的弱点来预测利用它的时间或事件吗?诸如在电子游戏中生成代币或作弊之类的事情?

Does anybody know if there was a time or event where somebody used rand()'s weakness in order to predict exploit it? Something like generating tokens or cheating in video games?

在 PHP 7 之前,rand() 很容易被破解.事实上,这里有一些 C 代码,归功于 Peter Selinger,可以预测给定种子的值:

Since prior to PHP 7, rand() was very easy to crack. In fact here is some C code, credit to Peter Selinger, that predicts the values given a seed:

#include <stdio.h>

#define MAX 1000
#define seed 1

main() {
  int r[MAX];
  int i;

  r[0] = seed;
  for (i=1; i<31; i++) {
    r[i] = (16807LL * r[i-1]) % 2147483647;
    if (r[i] < 0) {
      r[i] += 2147483647;
    }
  }
  for (i=31; i<34; i++) {
    r[i] = r[i-31];
  }
  for (i=34; i<344; i++) {
    r[i] = r[i-31] + r[i-3];
  }
  for (i=344; i<MAX; i++) {
    r[i] = r[i-31] + r[i-3];
    printf("%d\n", ((unsigned int)r[i]) >> 1);
  }
}

再说一次,有没有使用这个弱点来预测下一个随机数并利用某些东西的时候?

So once again, was there a time when this weakness was used in order to predict the next random number and exploit something?

谢谢!

推荐答案

在 PHP 7 之前,PHP 使用 LinearCongruential Generator 算法生成一个随机数或简称 LCG.该算法的工作原理如下:

Before PHP 7, PHP use Linear Congruential Generator algorithm to generate a random number or in short LCG. The algorithm works as follow:

 next_random = (previous_random * a + c) % m
 previous_random = next_random

当你第一次做随机数时,显然没有previous_random 数.这就是我们提供种子的原因.所以,种子只是第一个 previous_random 值.

When you first make a random, obviously, there is no previous_random number. That's why we provide seed. So, seed is just a first previous_random value.

现在,我们知道了算法,但我们需要知道 PHP 使用的 acm 的值是什么.我相信每个版本的 PHP 都使用不同的值.但是假设我们不知道这些值,我们如何猜测这个值.就我而言,我使用的是 PHP 5.6.15 Windows.

Now, we know the algorithm, but we need to know what the value of a, c, and m that PHP use. I believe that each version of PHP use different value for those. But let say we do not know those value, how do we guess this value. In my case, I am using PHP 5.6.15 Windows.

srand(0);
var_dump(rand());  // 12345
var_dump(rand());  // 5758

所以,m = getrandmax() + 1.由于我们的种子是 0,所以我们的 c = 12345.为了得到值a,我们可以使用简单的循环来猜测a.

So, m = getrandmax () + 1. Since our seed is 0, so our c = 12345. To get value a, we can use simple loop to guess a.

$m  = getrandmax () + 1;
for($a = 0; $a < $m; $a++)
   if ((($a * 12345 + 12345) % $m) == 5758) 
       var_dump($a);  // in my case, 20077

或者你可以像这样获得价值a

or you can get value a like this

srand(0); rand(); // 12345
srand(1); rand(); // 32422
// so a = 32422 - 12345 = 20077

现在,我可以编写与当前 PHP 版本相同的随机函数.

Now, I am able to write the same random function as my current PHP version.

class visal_rnd 
{
    function __construct($seed = 0) {
        $this->seed = $seed;
    }

    function rnd() {
        $this->seed = ($this->seed * 20077 + 12345) % 32768;
        return $this->seed;
    }
}

不过

我能够预测我自己的 PHP 版本,因为我对我当前的环境有很多了解,我知道一些以前的随机,我知道种子.如果攻击者的知识几乎为零,就不容易被攻击.

However

I was able to predict my own PHP version because I have so much knowledge about my current environment, I know a few previous random, I know the seed. If the attacker has almost zero knowledge, it would not be easy to attack.

PHP 7.0+,默认使用 Mersenne Twister.有比线性同余生成器更多的参数需要猜测.所以,它需要更多的知识.

PHP 7.0+, by default, use Mersenne Twister. There are more parameters to be guessed than Linear Congruential Generator. So, it requires more knowledge.

取决于您向公众公开了多少信息.如果你只生成一个随机数,而攻击者不知道 aprevious_randomcm.攻击者不可能预测下一个随机数.

Depends on how much information you have exposed to the public. If you generate only one random number and attacker has no knowledge of a, previous_random, c and m. It is impossible for attackers to predict the next random number.

这篇关于PHP 的 rand() 函数是否曾被用作漏洞利用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆