Was there a a time when PHP's rand() function was used as an exploit?

放肆的年华 提交于 2020-01-07 07:28:26

问题


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?

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?

Thanks!


回答1:


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

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.

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

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

or you can get value a like this

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

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;
    }
}

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.

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.

Is Linear Congruential Generator Bad?

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.



来源:https://stackoverflow.com/questions/44985462/was-there-a-a-time-when-phps-rand-function-was-used-as-an-exploit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!