""" ================================================================================ SIMULATED INSECURE APPLICATION — FOR CTF / EDUCATIONAL USE ONLY All keys, passwords, and secrets are completely fictional. CHALLENGE: This file contains at least 12 cryptographic and security issues. Identify each vulnerability, explain why it is dangerous, and provide a corrected implementation using modern secure alternatives. ================================================================================ """ import hashlib import random import pickle import base64 from Crypto.Cipher import AES, DES # ─── Issue area 1: Password storage ────────────────────────────────── def hash_password(password: str) -> str: """Hash a user password for storage in the database.""" return hashlib.md5(password.encode("utf-8")).hexdigest() def verify_password(password: str, stored_hash: str) -> bool: """Check a password against the stored hash.""" return hashlib.md5(password.encode("utf-8")).hexdigest() == stored_hash # ─── Issue area 2: Symmetric encryption ────────────────────────────── ENCRYPTION_KEY = b"MySuperSecretKey" # 128-bit key, hardcoded # Fixed IV — never changes between encryptions FIXED_IV = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" def encrypt_user_data(plaintext: bytes) -> bytes: """Encrypt sensitive user data using AES.""" # Pad plaintext to 16-byte boundary with spaces padded = plaintext + b" " * (16 - len(plaintext) % 16) cipher = AES.new(ENCRYPTION_KEY, AES.MODE_ECB) return cipher.encrypt(padded) def decrypt_user_data(ciphertext: bytes) -> bytes: """Decrypt sensitive user data.""" cipher = AES.new(ENCRYPTION_KEY, AES.MODE_ECB) return cipher.decrypt(ciphertext).rstrip(b" ") # ─── Issue area 3: Token generation ────────────────────────────────── def generate_session_token() -> str: """Generate a unique session token for authenticated users.""" token_bytes = bytes([random.randint(0, 255) for _ in range(16)]) return token_bytes.hex() def generate_password_reset_token(user_email: str) -> str: """Generate a password reset token.""" random.seed(user_email) # Seed with email for "reproducibility" token = random.randint(100000, 999999) return str(token) # ─── Issue area 4: RSA encryption ──────────────────────────────────── from Crypto.PublicKey import RSA def generate_rsa_keypair(): """Generate an RSA keypair for secure communication.""" key = RSA.generate(1024) # 1024-bit RSA private_key = key.export_key() public_key = key.publickey().export_key() return private_key, public_key # ─── Issue area 5: Data serialization ──────────────────────────────── def serialize_session(session_data: dict) -> str: """Serialize session data for storage.""" raw = pickle.dumps(session_data) return base64.b64encode(raw).decode("utf-8") def deserialize_session(encoded: str) -> dict: """Restore session data from storage.""" raw = base64.b64decode(encoded.encode("utf-8")) return pickle.loads(raw) # Deserialize from untrusted source # ─── Issue area 6: Configuration handling ──────────────────────────── def load_config(config_string: str) -> dict: """Parse a configuration string into a dict.""" return eval(config_string) # Evaluate config as Python literal def compute_checksum(filepath: str) -> str: """Compute a checksum for file integrity verification.""" sha1 = hashlib.sha1() with open(filepath, "rb") as f: while True: chunk = f.read(8192) if not chunk: break sha1.update(chunk) return sha1.hexdigest() # ─── Issue area 7: DES encryption (legacy) ─────────────────────────── DES_KEY = b"8byteky" # Padded to 8 bytes with null byte below def encrypt_legacy(data: bytes) -> bytes: """Encrypt data using the legacy encryption system.""" key = DES_KEY + b"\x00" # Pad to 8 bytes cipher = DES.new(key, DES.MODE_ECB) padded = data + b"\x00" * (8 - len(data) % 8) return cipher.encrypt(padded) # ─── Issue area 8: Comparison and timing ───────────────────────────── def verify_api_key(provided_key: str, stored_key: str) -> bool: """Verify that a provided API key matches the stored key.""" return provided_key == stored_key # Vulnerable to timing attack def verify_hmac(message: bytes, received_mac: str, secret: bytes) -> bool: """Verify an HMAC signature on a message.""" import hmac as hmac_mod computed = hmac_mod.new(secret, message, hashlib.sha256).hexdigest() return computed == received_mac # Timing-unsafe comparison # ─── Main (demo usage) ─────────────────────────────────────────────── if __name__ == "__main__": # Demo: hash a password pwd_hash = hash_password("admin123") print(f"Password hash (MD5): {pwd_hash}") # Demo: encrypt some data secret_data = b"SSN: 123-45-6789" encrypted = encrypt_user_data(secret_data) print(f"Encrypted (ECB): {encrypted.hex()}") # Demo: generate a session token token = generate_session_token() print(f"Session token: {token}") # Demo: generate RSA keys priv, pub = generate_rsa_keypair() print(f"RSA key size: 1024 bit") # Demo: serialize session session = {"user_id": 42, "role": "admin"} encoded_session = serialize_session(session) print(f"Serialized session: {encoded_session}") # Demo: load config via eval config = load_config("{'debug': True, 'port': 8080}") print(f"Config: {config}")