Как нужно делать пароли (How I Make My Passwords)
Как нужно делать пароли (How I Make My Passwords)
Platform: CUSTOM | Category: Crypto | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: AES-CBC decryption with recovered key, IV matching for seed verification, PRNG seed recovery via timestamp bruteforce, Timestamp extraction from WhatsApp screenshot
Summary
Walkthrough of the CUSTOM Crypto Как нужно делать пароли (How I Make My Passwords). Task: AES-CBC encrypted data with key generated using Python random seeded with time.time(). Solution: Extract timestamp from WhatsApp screenshot, bruteforce PRNG seeds around that time, verify by mat
Description
Недавно я гулял по Москве. И встретил в кафе крутого тим-лида одной компании! Теперь напишу ему, как делаю свои пароли. Думаю, он никогда не создавал их так удобно и безопасно :)
Files:
gen_pass.py- Python password generation scriptsample.txt- IV and encrypted datawhatsapp_chat.png- WhatsApp chat screenshot
Analysis
1. Generator source code (gen_pass.py)
python read-only • copy allowedfrom Crypto.Cipher import AES from Crypto.Util.Padding import pad import random import time KEY_LEN = 16 BS = 16 time_s = int(time.time()) random.seed(time_s) key = bytes([random.randint(0, 255) for _ in range(KEY_LEN)]) iv = bytes([random.randint(0, 255) for _ in range(BS)]) cipher = AES.new(key, AES.MODE_CBC, iv) final = cipher.encrypt(pad(passwd, BS))
Critical vulnerability: time.time() is used as seed for PRNG!
2. Data from sample.txt
IV: e49af1c15dad9962c45547b81414a399
Encrypted: 5239047215d18b79ffed9b8a93063e44a0ed0615ace44c8f80855775375bd85920dc6c0e37486ee2109887a55c337b66
3. WhatsApp screenshot
The screenshot shows:
- Date: November 01, 2023
- Time: ~17:10 (Moscow time)
- Message about password generation
Vulnerability
Python random module uses Mersenne Twister PRNG. With a known seed, all subsequent values are fully deterministic.
Attack:
- Determine approximate encryption time from the screenshot
- Bruteforce timestamps around that time
- For each timestamp, generate key and IV
- Compare generated IV with the known one
- When IV matches, use the key for decryption
Solution
python read-only • copy allowed#!/usr/bin/env python3 """ Hackerlab: Как нужно делать пароли PRNG seed bruteforce attack on AES-CBC """ from Crypto.Cipher import AES from Crypto.Util.Padding import unpad import random from datetime import datetime import pytz # Known values from sample.txt iv_hex = "e49af1c15dad9962c45547b81414a399" final_hex = "5239047215d18b79ffed9b8a93063e44a0ed0615ace44c8f80855775375bd85920dc6c0e37486ee2109887a55c337b66" iv = bytes.fromhex(iv_hex) final = bytes.fromhex(final_hex) KEY_LEN = 16 BS = 16 # Time from WhatsApp screenshot: 01 November 2023, ~17:10 Moscow time moscow_tz = pytz.timezone('Europe/Moscow') base_time = moscow_tz.localize(datetime(2023, 11, 1, 17, 10, 0)) base_timestamp = int(base_time.timestamp()) print(f"[*] Base timestamp: {base_timestamp}") print(f"[*] Searching in range [{base_timestamp - 300}, {base_timestamp + 300}]") # Bruteforce timestamps around the known time for offset in range(-300, 301): # +/- 5 minutes time_s = base_timestamp + offset # Reproduce PRNG state random.seed(time_s) key = bytes([random.randint(0, 255) for _ in range(KEY_LEN)]) test_iv = bytes([random.randint(0, 255) for _ in range(BS)]) # Check if IV matches if test_iv == iv: print(f"[+] Found matching timestamp: {time_s}") print(f"[+] Offset from base: {offset} seconds") print(f"[+] Key: {key.hex()}") # Decrypt the ciphertext cipher = AES.new(key, AES.MODE_CBC, iv) decrypted = unpad(cipher.decrypt(final), BS) print(f"[+] Decrypted: {decrypted.decode()}") break else: print("[-] No matching timestamp found in range")
Execution result
[*] Base timestamp: 1698847800
[*] Searching in range [1698847500, 1698848100]
[+] Found matching timestamp: 1698847827
[+] Offset from base: 27 seconds
[+] Key: <recovered_key>
[+] Decrypted: CODEBY{REDACTED}
Lessons
- Never use
randomfor cryptography - usesecretsoros.urandom()instead - Timestamp is a bad seed - easy to guess with second precision
- IV leak helps verification - allows checking seed correctness without decryption
- Metadata matters - chat screenshot provided time reference
Alternative Approaches
- Without time reference: Bruteforce all timestamps for the last N years (slower but works)
- With known plaintext: If flag format is known, can verify decryption directly
- Parallel bruteforce: Split the range into parts for speedup
References
- Python random module documentation
- Mersenne Twister PRNG
- CWE-330: Use of Insufficiently Random Values
Key Takeaways / Lessons
- Mastering AES-CBC decryption with recovered key, IV matching for seed verification, PRNG seed recovery via timestamp bruteforce, Timestamp extraction from WhatsApp screenshot was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-01-02 • CUSTOM • Как нужно делать пароли (How I Make My Passwords) • Difficulty: Easy