Кастом (Custom)
Кастом (Custom)
Platform: hackerlab | Category: Crypto | Type: Challenge | Difficulty: Medium | OS: NA | Author: XESXOR | Date: 2026-01-02 | Status: Solved Techniques: Known Plaintext Attack using flag format, Substitution cipher reversal, Leetspeak pattern recognition
Summary
Files: - 5d41402abc4b2a76b9719d911017c592.py - encryption script - encrypted.txt - encrypted text
Кастом (Custom) — hackerlab
Description
"Иногда полезно придумывать что-то своё. Это развивает креативность в человеке."
(Translation: "Sometimes it's useful to create something of your own. It develops creativity in a person.")
Files:
5d41402abc4b2a76b9719d911017c592.py- encryption scriptencrypted.txt- encrypted text
Analysis
Encryption Script
python read-only • copy allowedimport string import random import sys def generate_key(entrypoint): random.seed(entrypoint) letters = list(string.ascii_lowercase) key = list(letters) random.shuffle(key) return dict(zip(letters, key)) def encrypt(key, message): cipher = "" for c in message: if c in key: cipher += key[c] else: cipher += c return cipher entrypoint = sys.argv[0][::-1].upper() key = generate_key(entrypoint) FLAG = "CODEBY{REDACTED}".lower() cipher = encrypt(key, FLAG) with open('encrypted.txt', 'w') as file: file.write(cipher)
Key Observations
- Substitution cipher - simple letter substitution, numbers and symbols are not encrypted
- Seed depends on filename -
sys.argv[0][::-1].upper()= reversed script name - Filename = MD5("hello") -
5d41402abc4b2a76b9719d911017c592 - Encrypted text:
sgwahu{sfj70d_s1pm3v_1j_4kj0_fj3xf1}
Solution Approach
Instead of bruteforcing the seed (which would require knowing the exact filename at runtime), used Known Plaintext Attack:
- Flag starts with
codeby{→ ciphertext starts withsgwahu{ - This gives initial mapping:
s→c, g→o, w→d, a→e, h→b, u→y
Solution
Step 1: Building Initial Mapping
Ciphertext: sgwahu{sfj70d_s1pm3v_1j_4kj0_fj3xf1}
Known: codeby{..............................}
Mapping: s→c, g→o, w→d, a→e, h→b, u→y
Step 2: Partial Decryption
Applying the known mapping:
sgwahu{sfj70d_s1pm3v_1j_4kj0_fj3xf1}
codeby{c.s70d_c1.h3._1s_4.s0_.s3.f1}
Step 3: Recognizing Leetspeak Patterns
Analyzing the partially decrypted text:
c.s70d→cus70m(custom) →f→uc1.h3.→c1ph3r(cipher) →p→p, m→h, v→r1s→1s(is) →j→s4.s0→4ls0(also) →k→l.s3.f1→us3fu1(useful) →x→f
Step 4: Complete Mapping
python read-only • copy allowedcipher_to_plain = { 's': 'c', 'g': 'o', 'w': 'd', 'a': 'e', 'h': 'b', 'u': 'y', 'f': 'u', 'j': 's', 'd': 'm', 'p': 'p', 'm': 'h', 'v': 'r', 'k': 'l', 'x': 'f' } ciphertext = "sgwahu{sfj70d_s1pm3v_1j_4kj0_fj3xf1}" plaintext = "" for c in ciphertext: if c in cipher_to_plain: plaintext += cipher_to_plain[c] else: plaintext += c print(plaintext) # codeby{REDACTED}
Decrypted Message
REDACTED
custom cipher is also useful
The message matches the task description about the usefulness of creating something of your own!
Alternative Approach
Could have tried to recover the seed:
- Filename:
5d41402abc4b2a76b9719d911017c592.py - Reversed:
yp.295c26f8e710119d9179b67a2b4cba20414d5 - Uppercase:
YP.295C26F8E710119D9179B67A2B4CBA20414D5
But Known Plaintext Attack turned out to be simpler and more reliable.
Lessons
- Custom cipher ≠ secure cipher - a custom cipher does not mean a secure one
- Known Plaintext Attack is effective against substitution ciphers
- Leetspeak helps guess words even with partial decryption
- The filename (MD5 hash) was a red herring