Use of Predictable Algorithm in Random Number Generator in phpservermon/phpservermon
Reported on
Jun 20th 2021
✍️ Description
Insecure randomness errors occur when a function that can produce predictable values is used as a source of randomness in security-sensitive context. This code uses the rand() function to generate "unique" identifiers for the receipt pages it generates. In this case the function that generates weak random numbers is mt_rand() in User.php at line 324.
🕵️♂️ Proof of Concept
**poc.php**
#!/usr/bin/env php
<?php
if($argc < 3)
{
print($argv[0] . ' <seed> <n>' . "\n");
print('' . "\n");
print('Parameters:' . "\n");
print(' seed: Seed to initialize mt_rand() with' . "\n");
print(' offset: Number of calls to mt_rand() before printing the first');
print(' output' . "\n");
print('' . "\n");
print('Output:' . "\n");
print(' <offset>\'s call to mt_rand() and <offset+227>\'s call');
print(' to mt_rand()' . "\n");
exit();
}
mt_srand($argv[1]);
for($i=0;$i<$argv[2];$i++)
mt_rand();
print mt_rand() . " ";
for($i=0;$i<226;$i++)
mt_rand();
print mt_rand() . "\n";
💥 Impact
The random number generator implemented by mt_rand() cannot withstand a cryptographic attack. Because rand() is a statistical PRNG, it is easy for an attacker to guess the strings it generates.
🕵️♂️ Solution
When unpredictability is critical, as is the case with most security-sensitive uses of randomness, use a cryptographic PRNG. Regardless of the PRNG you choose, always use a value with sufficient entropy to seed the algorithm. (Values such as the current time offer only negligible entropy and should not be used.)
Occurrences
Hi Akshay, I've just emailed the maintainer of phpservermon about this vulnerability and am waiting to hear back. Good job!
Hi Akshay, Thank you for reporting this possible vulnerability.
Before log in by remember me token, we check if the hash in the cookies matched the hash on the serverside. The hash exists of the user_id, hashed mt_rand() token and a secret key. Although the mt_rand() could be improved I think that the Secret key prevents the vulnerability from being used. What are your thoughts on this?
Thank you phpservermon maintainer! Akshay, just pinging you to kindly take a look at this ❤️
Hi phpservermon maintainer, I understand your point of using secret key to protect the flow. I just one hypothetical scenario about this flow is. Just by any mean if secret key got compromised by any mean (such as chaining this vulnerability with XSS/Phishing to steal secret keys) then it can create an issue.
However, I always suggest to improve the code in best possible way to make the application more safe and secure. So, I still suggest you to move to PRNG.
Also, while re-analyzing this scenario, I found that there's one more affected instance which I missed earlier.
Second instance is used to create reset hash of any user. I am creating different detailed ticket for that. (In this case, an attacker will able to predict possible reset password hashes of users)
Because of the need for chaining vulnerabilities or the use of social engineering, I don't think this vulnerability has been exploited yet. Before someone does, lets patch this! Thank you for your research 🔬 .