Слово за слово (Word for Word)
Слово за слово (Word for Word)
Platform: CUSTOM | Category: Crypto | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: Character-by-character hash reversal, MD5 rainbow table attack on single characters, Precomputed hash lookup table
Summary
Walkthrough of the CUSTOM Crypto Слово за слово (Word for Word). Task: 43 MD5 hashes separated by spaces. Solution: Each hash is MD5 of a single character; build a lookup table for all printable ASCII characters and decode the flag character by character.
Description
"В школе Вы часто списывали? Если это так, то данное задание не вызовет у Вас трудностей. А тем, кто привык всё делать сам - соболезнуем"
Translation: "Did you often cheat in school? If so, this task won't be difficult for you. And for those who are used to doing everything themselves - our condolences"
Analysis
The file word for word.txt contains a string of 43 MD5 hashes separated by spaces:
0d61f8370cad1d412f80b84d143e1257 f186217753c37b9b9f958d906208506e f623e75af30e62bbd73d6df5b50bb7b5 3a3ea00cfc35332cedf6e5e9a32e94da 9d5ed678fe57bcca610140957afab571 ...
Key observations:
- 43 hashes = 43 characters — typical length for a flag in
CODEBY{...}format - Each hash is 32 hex characters — standard MD5
- Title "Слово за слово" (Word for Word) — hints at letter-by-letter copying/lookup
- Description about "cheating" — suggests using precomputed tables (rainbow tables)
Hypothesis: Each MD5 hash is a hash of a single character. We need to create a lookup table for all possible characters and find matches.
Verifying the Hypothesis
python read-only • copy allowedimport hashlib # Check the first hash test_hash = "0d61f8370cad1d412f80b84d143e1257" for c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ": if hashlib.md5(c.encode()).hexdigest() == test_hash: print(f"Found: '{c}'") break # Output: Found: 'C'
The first hash corresponds to the letter 'C' — the beginning of the flag CODEBY!
Solution
python read-only • copy allowed#!/usr/bin/env python3 import hashlib # Read the file with hashes with open("word for word.txt", "r") as f: content = f.read().strip() hashes = content.split() # Create a lookup table for all possible characters chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_{}-!@#$%^&*().,;:' " hash_to_char = {} for c in chars: h = hashlib.md5(c.encode()).hexdigest() hash_to_char[h] = c # Decode each hash result = [] for h in hashes: if h in hash_to_char: result.append(hash_to_char[h]) else: result.append('?') # Unknown character flag = "".join(result) print(flag)
Output:
CODEBY{REDACTED}
Alternative Solution: Online Services
You can use online MD5 rainbow tables:
Each hash is looked up separately, and the results are combined into a string.
Why This Works
MD5 hash of a single character is easy to crack:
- Only ~95 printable ASCII characters
- All 95 hashes can be precomputed in milliseconds
- Rainbow table for single characters is trivial
Important: This attack works ONLY for hashes of single characters. For hashes of words or phrases, you need full rainbow tables or brute-force.
Hash Table
| Character | MD5 Hash |
|---|---|
| C | 0d61f8370cad1d412f80b84d143e1257 |
| O | f186217753c37b9b9f958d906208506e |
| D | f623e75af30e62bbd73d6df5b50bb7b5 |
| E | 3a3ea00cfc35332cedf6e5e9a32e94da |
| B | 9d5ed678fe57bcca610140957afab571 |
| ... | ... |
Related Techniques
- Rainbow table attack — precomputed hash tables
- Dictionary attack — attack using a wordlist
- Brute-force — exhaustive search
- Hash identification — determining hash type by length/format
Key Takeaways / Lessons
- Mastering Character-by-character hash reversal, MD5 rainbow table attack on single characters, Precomputed hash lookup table was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-01-02 • CUSTOM • Слово за слово (Word for Word) • Difficulty: Easy