Use of Predictable Algorithm in Random Number Generator in phpservermon/phpservermon

Valid

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.)

Occurences

Ziding Zhang
6 months ago

Admin


Hi Akshay, I've just emailed the maintainer of phpservermon about this vulnerability and am waiting to hear back. Good job!

We have contacted a member of the phpservermon team and are waiting to hear back 6 months ago
phpservermon/phpservermon maintainer
6 months ago

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?

Ziding Zhang
6 months ago

Admin


Thank you phpservermon maintainer! Akshay, just pinging you to kindly take a look at this ❤️

Akshay Jain
5 months ago

Researcher


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.

Akshay Jain
5 months ago

Researcher


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)

Tim Zandbergen
5 months ago

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 🔬 .

Tim Zandbergen validated this vulnerability 5 months ago
Akshay Jain has been awarded the disclosure bounty
The fix bounty is now up for grabs
Tim Zandbergen confirmed that a fix has been merged on bb10a5 5 months ago
Tim Zandbergen has been awarded the fix bounty