Home Backend Development PHP Tutorial Detailed explanation of safe examples of mt_rand() random numbers in PHP

Detailed explanation of safe examples of mt_rand() random numbers in PHP

Jan 06, 2018 pm 04:09 PM
php rand random number

I discovered a lot of security vulnerabilities related to mt_rand() some time ago, which were basically caused by misunderstanding the usage of random numbers. Here I would like to mention another pitfall of the PHP official website manual. Take a look at the introduction to mt_rand(): Chinese version ^cn English version ^en. You can see that the English version has an extra yellow Caution warning. mt_rand() uses the mersennetwister algorithm to return random integers. Everyone knows this, but the following article mainly introduces you to the relevant information about the security of mt_rand() random numbers in PHP. The introduction in the article is very detailed. Friends who need it can refer to it. For reference, let’s learn with the editor below.

Many domestic developers probably read the Chinese version of the introduction and used mt_rand() in the program to generate security tokens, core encryption and decryption keys, etc., causing serious security problems.

Pseudo-random number

mt_rand() is not a true random number generating function. In fact, the random number functions in most programming languages ​​generate pseudo-random numbers. number. The difference between true random numbers and pseudo-random numbers will not be explained here. You only need to briefly understand a little bit

Pseudo-random is generated by a determinable function (commonly used linear congruence) through a seed (commonly used clock) of pseudo-random numbers. This means that if you know the seed, or the random number that has been generated, it is possible to obtain information about the next random number sequence (predictability).

Simply assume that the function that generates random numbers internally in mt_rand() is: rand = seed+(i*10) where seed is the random number seed, and i is the number of times this random number function is called. When we know the two values ​​​​of i and rand at the same time, we can easily calculate the value of seed. For example, rand=21 and i=2 are substituted into the function 21=seed+(2*10) to get seed=1. Isn't it very simple? After we get the seed, we can calculate the value of rand when i is any value.

PHP's automatic seeding

We already know from the previous section that every time mt_rand() is called, a pseudo-random number will be calculated based on seed and the current number of calls i. And the seed is automatically seeded:

Note: Since PHP 4.2.0, there is no need to use srand() or mt_srand() to seed the random number generator, because it is now done automatically by the system.

Then the question arises, when does the system automatically complete the seeding? If mt_rand() is automatically seeded every time, then there is no point in cracking the seed. The manual does not give detailed information on this point. I searched all over the Internet but couldn't find a reliable answer. I could only look at the source code ^mtrand:

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) );
}
Copy after login

You can see that every time mt_rand() is called, it will first check whether it has been sown. If it has been sown, generate random numbers directly, otherwise call php_mt_srand to sow. That is to say, during each php cgi process, only the first call to mt_rand() will automatically seed. Next, random numbers will be generated based on this first sown seed. Among the several operating modes of php, except CGI (each request starts a cgi process and closes it after the request is completed. The php.ini environment variables must be re-read every time, resulting in low efficiency, and it should not be used much now) , basically, after one process processes the request, the standby waits for the next one, and it will not be recycled until multiple requests are processed (it will also be recycled after timeout).

Write a script to test it

<?php
//pid.php
echo getmypid();
Copy after login
<?php
//test.php
$old_pid = file_get_contents('http://localhost/pid.php');
$i=1;
while(true){
 $i++;
 $pid = file_get_contents('http://localhost/pid.php');
 if($pid!=$old_pid){
 echo $i;
 break;
 }
}
Copy after login

Test results: (windows+phpstudy)

apache 1000 requests

nginx 500 requests

Of course, this test only confirms the number of requests that apache and nginx can handle in one process. Let's verify the conclusion just now about automatic seeding:

<?php
//pid1.php
if(isset($_GET['rand'])){
 echo mt_rand();
}else{
 echo getmypid();
}
Copy after login
<?php
//pid2.php
echo mt_rand();
Copy after login
<?php
//test.php
$old_pid = file_get_contents('http://localhost/pid1.php');
echo "old_pid:{$old_pid}\r\n";
while(true){
 $pid = file_get_contents('http://localhost/pid1.php');
 if($pid!=$old_pid){
 echo "new_pid:{$pid}\r\n";
 for($i=0;$i<20;$i++){
  $random = mt_rand(1,2);
  echo file_get_contents("http://localhost/pid".$random.".php?rand=1")." ";
 }

 break;
 }
}
Copy after login

Judged by pid, when a new process starts, two randomly obtained The output of mt_rand() on one of the pages:

old_pid:972 new_pid:7752 1513334371 2014450250 1319669412 499559587 117728762 1465174656 1671827592 1703046841 464496438 1974338231 46646067 981271768 1070717272 571887250 922467166 606646473 134605134 857256637 1971727275 2104203195
Copy after login

Take the first random number 1513334371 to explode the seeds:

smldhz@vm:~/php_mt_seed-3.2$ ./php_mt_seed 1513334371 Found 0, trying 704643072 - 738197503, speed 28562751 seeds per second seed = 735487048 Found 1, trying 1308622848 - 1342177279, speed 28824291 seeds per second seed = 1337331453 Found 2, trying 3254779904 - 3288334335, speed 28811010 seeds per second seed = 3283082581 Found 3, trying 4261412864 - 4294967295, speed 28677071 seeds per second Found 3
Copy after login

Exploded 3 possible seeds, the number is very small, manually one by one Test:

<?php
mt_srand(735487048);//手工播种
for($i=0;$i<21;$i++){
 echo mt_rand()." ";
}
Copy after login

Output:

The first 20 digits are exactly the same as those obtained by the above script. The confirmed seed is 1513334371. With the seed, we can calculate the random number generated by calling mt_rand() any number of times. For example, I generated 21 digits in this script, and the last digit is 1515656265. If you have not visited the site after running the script just now, you can see the same 1515656265 by opening http://localhost/pid2.php.

So we get the conclusion:

php's automatic seeding occurs when mt_rand() is called for the first time in the php cgi process. Regardless of the page visited, as long as the request is processed by the same process, they will share the same initially automatically sown seed.

php_mt_seed

We already know that the generation of random numbers depends on a specific function, which was assumed above to be rand = seed+(i*10). For such a simple function, we can of course directly calculate (orally) a (set of) solution, but the function actually used by mt_rand() is quite complex and cannot be inverted. An effective cracking method is to exhaustively enumerate all seeds, generate a random number sequence based on the seed, and then compare it with a known random number sequence to verify whether the seed is correct. php_mt_seed^phpmtseed is such a tool. It is very fast and it only takes a few minutes to run the 2^32-bit seed. It can directly explode possible seeds based on the output of a single mt_rand() (example above). Of course, it can also explode seeds that limit the MIN MAX output like mt_rand(1,100) (useful in the examples below).

Security Issues

Having said so much, why are random numbers unsafe? In fact, there is nothing wrong with the function itself. The official also clearly states that the generated random numbers should not be used for security encryption purposes (although the Chinese version manual does not write this). The problem is that the developers don't realize that this is not a truly random number. We already know that seeds can be exploded from a known sequence of random numbers. In other words, as long as there is an output random number or its derivative value (reversible random value) in any page, then the random number in any other page will no longer be a "random number". Common examples of outputting random numbers include verification codes, random file names, etc. Common random numbers are used for security verification, such as retrieving password verification values, such as encryption keys, etc. An ideal attack scenario:

In the dead of night, waiting for apache (nginx) to take back all PHP processes (to ensure that the next visit will be re-seeded), visit the verification code page once, reverse the random number based on the verification code characters, and then Explode random number seeds based on random numbers. Then visit the password retrieval page, and the generated password retrieval link is based on random numbers. We can easily calculate this link and retrieve the administrator's password...XXOO

Example

PHPCMS MT_RAND SEED CRACK causing authkey leakage Yu Niu writes better than me , it’s enough to look at his

Discuz x3.2 authkey leak is actually similar. The official patch has been released, and those who are interested can analyze it themselves.

Related recommendations:

PHP’s true and false random numbers

php’s rand() function for random number generation

Example of JavaScript implementation of random number deduplication generator

The above is the detailed content of Detailed explanation of safe examples of mt_rand() random numbers in PHP. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Roblox: Bubble Gum Simulator Infinity - How To Get And Use Royal Keys
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Fusion System, Explained
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers Of The Witch Tree - How To Unlock The Grappling Hook
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1666
14
PHP Tutorial
1273
29
C# Tutorial
1253
24
PHP and Python: Comparing Two Popular Programming Languages PHP and Python: Comparing Two Popular Programming Languages Apr 14, 2025 am 12:13 AM

PHP and Python each have their own advantages, and choose according to project requirements. 1.PHP is suitable for web development, especially for rapid development and maintenance of websites. 2. Python is suitable for data science, machine learning and artificial intelligence, with concise syntax and suitable for beginners.

PHP: A Key Language for Web Development PHP: A Key Language for Web Development Apr 13, 2025 am 12:08 AM

PHP is a scripting language widely used on the server side, especially suitable for web development. 1.PHP can embed HTML, process HTTP requests and responses, and supports a variety of databases. 2.PHP is used to generate dynamic web content, process form data, access databases, etc., with strong community support and open source resources. 3. PHP is an interpreted language, and the execution process includes lexical analysis, grammatical analysis, compilation and execution. 4.PHP can be combined with MySQL for advanced applications such as user registration systems. 5. When debugging PHP, you can use functions such as error_reporting() and var_dump(). 6. Optimize PHP code to use caching mechanisms, optimize database queries and use built-in functions. 7

PHP in Action: Real-World Examples and Applications PHP in Action: Real-World Examples and Applications Apr 14, 2025 am 12:19 AM

PHP is widely used in e-commerce, content management systems and API development. 1) E-commerce: used for shopping cart function and payment processing. 2) Content management system: used for dynamic content generation and user management. 3) API development: used for RESTful API development and API security. Through performance optimization and best practices, the efficiency and maintainability of PHP applications are improved.

PHP vs. Python: Understanding the Differences PHP vs. Python: Understanding the Differences Apr 11, 2025 am 12:15 AM

PHP and Python each have their own advantages, and the choice should be based on project requirements. 1.PHP is suitable for web development, with simple syntax and high execution efficiency. 2. Python is suitable for data science and machine learning, with concise syntax and rich libraries.

The Enduring Relevance of PHP: Is It Still Alive? The Enduring Relevance of PHP: Is It Still Alive? Apr 14, 2025 am 12:12 AM

PHP is still dynamic and still occupies an important position in the field of modern programming. 1) PHP's simplicity and powerful community support make it widely used in web development; 2) Its flexibility and stability make it outstanding in handling web forms, database operations and file processing; 3) PHP is constantly evolving and optimizing, suitable for beginners and experienced developers.

PHP and Python: Code Examples and Comparison PHP and Python: Code Examples and Comparison Apr 15, 2025 am 12:07 AM

PHP and Python have their own advantages and disadvantages, and the choice depends on project needs and personal preferences. 1.PHP is suitable for rapid development and maintenance of large-scale web applications. 2. Python dominates the field of data science and machine learning.

PHP vs. Other Languages: A Comparison PHP vs. Other Languages: A Comparison Apr 13, 2025 am 12:19 AM

PHP is suitable for web development, especially in rapid development and processing dynamic content, but is not good at data science and enterprise-level applications. Compared with Python, PHP has more advantages in web development, but is not as good as Python in the field of data science; compared with Java, PHP performs worse in enterprise-level applications, but is more flexible in web development; compared with JavaScript, PHP is more concise in back-end development, but is not as good as JavaScript in front-end development.

PHP and Python: Different Paradigms Explained PHP and Python: Different Paradigms Explained Apr 18, 2025 am 12:26 AM

PHP is mainly procedural programming, but also supports object-oriented programming (OOP); Python supports a variety of paradigms, including OOP, functional and procedural programming. PHP is suitable for web development, and Python is suitable for a variety of applications such as data analysis and machine learning.

See all articles