2416 words
12 minutes
Echo Response - Week 3 Quantum Conundrum - Investigation Report

Investigation Report#

Quantum Conundrum - Security Assessment Report#

Date: October 21, 2025
Investigator: MR. Umair
Case: Megacorp Quantum Encryption System Analysis
Target: Obscurarium Realm Defense Systems
Challenge: Break the “Unbreakable” Quantum-Proof Cipher


Executive Summary#

Megacorp Quantum, a vital stronghold of security infrastructure safeguarded by the Obscurarium Realm, claims to possess “unbreakable” and “quantum-proof” defenses protecting the Obscuran Key - one of three Primal Keys capable of rewriting the history of the Cyber Realms.

Assessment Result: SYSTEM COMPROMISED

Despite the architects’ confidence that “no cipher, no codecaster, no force magical or digital can bypass their quantum-safe architecture,” the encryption system has been fully reverse-engineered and broken.

Key Findings:

  • Public key encoding identified and decoded
  • Seed generation algorithm reverse-engineered
  • Complete decryption process reconstructed (7 transformation layers)
  • Encrypted file successfully decrypted
  • Flag extracted: OS{BENDER}
  • All 4 investigation objectives achieved

Strategic Impact: The Obscuran Key’s protection has been breached. Confidence is no defense against determined reverse engineering.


Detailed Investigation Findings#

1 Public Key Analysis and Decoding#

Question: Analyze the file publickey.pubkey and review its contents. Decode the value and enter it as an answer to this exercise. Make sure to also include in your answer what encoding algorithm was used and what the decoded values represent.

Answer:#

Encoding Algorithm: Base64

Decoded Value: 24.07.2025|megacorp@quantum.com

What It Represents: A static string containing a date and email address used as input for seed generation in the encryption/decryption process.


Evidence Analysis:#

File Location: publickey.pubkey

Raw Contents (Base64-encoded):

MjQuMDcuMjAyNXxtZWdhY29ycEBxdWFudHVtLmNvbQ==

Decoding Process:

import base64
encoded = "MjQuMDcuMjAyNXxtZWdhY29ycEBxdWFudHVtLmNvbQ=="
decoded = base64.b64decode(encoded).decode('utf-8')
print(decoded)
# Output: 24.07.2025|megacorp@quantum.com

Structure Breakdown:

  • Date Component: 24.07.2025 (Day.Month.Year format)
    • Day: 24
    • Month: 07 (July)
    • Year: 2025
  • Separator: | (pipe character)
  • Email Component: megacorp@quantum.com

Purpose in Encryption System: This decoded string serves as a static component of the seed generation algorithm. It combines with other dynamic elements (timestamp, salt) to create the encryption/decryption seed.


Why Base64?#

Characteristics:

  • Standard encoding method (RFC 4648)
  • Converts binary data to ASCII text
  • Uses 64-character set: A-Z, a-z, 0-9, +, /
  • Padding with = characters
  • NOT encryption - purely encoding

Identification:

  • Ends with == (padding indicator)
  • Only contains alphanumeric characters and =
  • No special characters or symbols

Security Implication: CRITICAL WEAKNESS

  • Base64 is encoding, not encryption
  • Provides zero security or obfuscation
  • Trivially reversible
  • Public key should use asymmetric cryptography (RSA, ECC), not simple encoding

2 Seed Calculation Investigation#

Question: Investigate how the Seed is calculated with the information from the publickey.pubkey. What other data is used to calculate the seed?

Answer:#

Seed Calculation Uses:

  1. Date from public key: 24.07.2025
  2. Email from public key: megacorp@quantum.com
  3. Secret string: PublicSalt
  4. Timestamp from file: 2025-07-24T11:00:00Z

Seed Generation Algorithm:#

Formula:

seed = EMAIL + DATE + TIMESTAMP + SALT

Full Seed Example:

megacorp@quantum.com24.07.20252025-07-24T11:00:00ZPublicSalt

Components Breakdown:

ComponentValueSourceType
Emailmegacorp@quantum.compublickey.pubkey (Base64 decoded)Static
Date24.07.2025publickey.pubkey (Base64 decoded)Static
Timestamp2025-07-24T11:00:00ZEncrypted file metadataDynamic
SaltPublicSaltHardcoded constantStatic

How the Timestamp is Obtained:#

File Structure: The encrypted file (decrypt_me.enc) has a specific structure:

[Encrypted Data: N bytes] [Timestamp: variable length] [Metadata: 8 bytes]

Metadata Layout (last 8 bytes):

  • Bytes -8 to -4: Timestamp length (4 bytes, little-endian integer)
  • Bytes -4 to end: Matrix dimension N (4 bytes, little-endian integer)

Extraction Code:

data = Path("decrypt_me.txt.enc").read_bytes()
ts_len = int.from_bytes(data[-8:-4], "little")
n = int.from_bytes(data[-4:], "little")
timestamp = data[-8 - ts_len:-8].decode("ascii")

Example:

  • If ts_len = 20 and n = 64
  • Timestamp is stored at bytes [-28:-8]
  • Value: 2025-07-24T11:00:00Z (ISO 8601 format)

Security Analysis:#

Weaknesses Identified:

  1. Hardcoded Salt

    • PublicSalt is a constant, not truly random
    • Same salt used for all encryptions
    • Does not provide cryptographic security
  2. Predictable Date

    • Date from public key is static
    • Known to anyone with access to public key
    • Reduces entropy of seed
  3. ISO Timestamp Format

    • Standard format is predictable
    • Only changes per encryption instance
    • Limited entropy (time-based guessing possible)
  4. No Key Derivation Function (KDF)

    • Simple concatenation, no PBKDF2/Argon2/scrypt
    • No computational hardness
    • Vulnerable to brute-force if seed guessed

Proper Implementation Should Use:

  • Random salt per encryption
  • Strong KDF (PBKDF2, Argon2, scrypt)
  • High iteration count
  • Additional entropy sources

3 Reverse Engineering: Transformation Analysis#

Question: Reverse engineer the decryption program and identify how many distinct transform passes are applied before the final XOR mask? Submit the number of distinct transformations and briefly explain what the first three transformations of the encryption process are doing.

Answer:#

Number of passes before the final XOR: 7

First Three Transformations:

  1. Ring rotation: Rotates each concentric layer of the NN grid 90 clockwise. This physically rearranges the spatial layout by treating the matrix like onion rings, where each ring (outer, inner, etc.) rotates independently.

  2. Add constant pass: Adds a byte constant (derived from year: 2025 & 0xFF = 225) to every cell modulo 256. This operation uniformly shifts all byte values across the entire matrix, providing initial value diffusion.

  3. Subtract constant pass: Subtracts a byte constant (derived from month: 7) from every cell modulo 256. This reverses some of the addition effect while maintaining byte-level confusion, creating a non-linear relationship between original and transformed values.


Complete Transformation Pipeline#

Reverse Engineering Methodology#

Tools Used:

  • Ghidra 11.2.1 - Disassembler and decompiler
  • Binary: QuantumConundrum.exe
  • Analysis: Static code analysis of decryption routine

Key Function: FUN_140002680 (Main orchestrating function)


The 7 Transformation Layers#

Transformation 1: Ring Rotation (90 Clockwise)#

Location: Inline block in FUN_140002680

Algorithm:

For an NN matrix, treat as concentric rings
For each ring (outer to inner):
Extract ring elements
Rotate 90 clockwise
Place back in matrix

Example (44 matrix):

Before Ring Rotation:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
After Ring Rotation:
13 9 5 1
14 10 6 2
15 11 7 3
16 12 8 4

Code Evidence:

  • Complex loop structure manipulating matrix indices
  • Processes rings from outermost to innermost
  • Uses temporary storage for rotation

Purpose:

  • Initial spatial scrambling
  • Makes linear analysis impossible
  • Each ring moves independently

Transformation 2: Add Constant (mod 256)#

Location: FUN_140002070

Algorithm:

add_val = year & 0xFF # 2025 & 0xFF = 225
for each cell in matrix:
cell = (cell + add_val) mod 256

Disassembled Code:

iVar9 = param_2 + *puVar6;
*puVar6 = iVar9 + ((int)((-(uint)(iVar9 < 0) & 0xff) + iVar9) >> 8) * -0x100;

Translation: (value + constant) & 0xFF

Example:

  • Cell value: 50
  • Add 225: 50 + 225 = 275
  • Mod 256: 275 mod 256 = 19

Purpose:

  • Uniform byte-level diffusion
  • Changes all values simultaneously
  • Modulo arithmetic prevents overflow

Transformation 3: Subtract Constant (mod 256)#

Location: FUN_1400021f0

Algorithm:

sub_val = month # July = 7
for each cell in matrix:
cell = (cell - sub_val + 256) mod 256

Disassembled Code:

iVar9 = (*puVar6 - param_2) + 0x100;
*puVar6 = iVar9 + ((int)((-(uint)(iVar9 < 0) & 0xff) + iVar9) >> 8) * -0x100;

Translation: (value - constant + 256) & 0xFF

Example:

  • Cell value: 50
  • Subtract 7: 50 - 7 + 256 = 299
  • Mod 256: 299 mod 256 = 43

Purpose:

  • Counter-intuitive: adds confusion after addition
  • Non-linear transformation
  • Different constant than add pass

Transformation 4: Row/Column Cyclic Shifts#

Location: FUN_140002390 (first part)

Algorithm:

shift = day % N # 24 % 64 = 24
# Rotate rows
rows.rotate(-shift)
# Rotate columns
for each row:
row.rotate(-shift)

Code Evidence:

lVar5 = (longlong)(param_2 % ((int)(lVar5 >> 2) - (int)(lVar5 >> 0x3f)));
// param_2 is day value, lVar5 is derived from matrix size

Visual Example (shift=2, 44):

Row shift left by 2:
[A B C D] [C D A B]
Column shift up by 2:
[1] [9]
[5] [13]
[9] [1]
[13] [5]

Purpose:

  • Positional permutation
  • Doesn’t change byte values
  • Based on date component (day)

Transformation 5: Transposition / Quadrant Swaps#

Location: Inline block after FUN_140002390

Algorithm:

Divide matrix into quadrants
Swap quadrants in specific pattern
May also transpose (swap rows/columns)

Code Pattern:

  • Complex index manipulation
  • Swapping uVar2 values between positions
  • Multiple nested loops

Conceptual:

[TL TR] [BR BL]
[BL BR] [TR TL]

Purpose:

  • Advanced geometric rearrangement
  • Breaks up patterns from previous transforms
  • Adds complexity layer

Transformation 6: Even/Odd Bit Swap (0x55 mask)#

Location: FUN_140002540

Algorithm:

def bit_flip_pairs(x):
return ((x >> 1) & 0x55) | ((x & 0x55) << 1)

Disassembled Code:

*puVar3 = (int)*puVar3 >> 1 & 0x55U | (*puVar3 & 0x55) << 1;

Bit-level Transformation:

Original: b b b b b b b b
After: b b b b b b b b
Example byte: 10110011 (179)
Result: 01101101 (109)
Mask 0x55 = 01010101 (isolates odd bits)
Mask 0xAA = 10101010 (isolates even bits)

Purpose:

  • Bit-level confusion
  • Makes byte analysis harder
  • Reversible transformation

Transformation 7: Per-Byte Variable Bit Rotation#

Location: Inline loop in FUN_140002680

Algorithm:

for r in range(N):
for c in range(N):
spin = (year + month + day + r + c) & 7
cell = rot_right(cell, spin)
def rot_right(x, amt):
amt &= 7 # 0-7 bits
return ((x >> amt) | ((x << (8 - amt)) & 0xFF)) & 0xFF

Disassembled Code:

uVar41 = uVar44 & 0x80000007; // rotation amount (0-7)
*(uint *)(...) = (iVar8 >> (8 - (byte)uVar41) | iVar8 << ((byte)uVar41)) & 0xff;

Example:

Position (2,3): rotation = (2025 + 7 + 24 + 2 + 3) & 7 = 5
Byte: 10110011
Rotate right 5 bits: 01101011

Purpose:

  • Position-dependent obfuscation
  • Final bit-level scrambling
  • Each byte rotates differently

Final Step: XOR with Keystream#

Location: FUN_140001df0 (keystream generation) + FUN_140001c00 (XOR application)

Algorithm:

def keystream(seed, need):
out = bytearray()
idx = 0
while len(out) < need:
for ch in seed:
out.append((ord(ch) * 7 + idx) & 0xFF)
idx += 1
if len(out) >= need:
break
return bytes(out)
# Apply XOR
plaintext = bytes(b ^ m for b, m in zip(ciphertext, mask))

Keystream Characteristics:

  • Deterministic based on seed
  • Uses simple arithmetic: (char_value * 7 + index) & 0xFF
  • No cryptographic strength (not a CSPRNG)

Decryption Script Analysis#

Complete Decryption Code#

#!/usr/bin/env python3
from pathlib import Path
from collections import deque
EMAIL = "megacorp@quantum.com"
DATE = "24.07.2025"
SALT = "PublicSalt"
FILE = Path("QuantumConundrum_Project/decrypt_me.txt.enc")
def rot_right(x, amt):
"""Rotate byte right by amt bits"""
amt &= 7
return ((x >> amt) | ((x << (8 - amt)) & 0xFF)) & 0xFF
def bit_flip_pairs(x):
"""Swap even/odd bit pairs"""
return ((x >> 1) & 0x55) | ((x & 0x55) << 1)
def keystream(seed, need):
"""Generate keystream from seed"""
out = bytearray()
idx = 0
while len(out) < need:
for ch in seed:
out.append((ord(ch) * 7 + idx) & 0xFF)
idx += 1
if len(out) >= need:
break
return bytes(out)
def decode(path):
# Read encrypted file
data = path.read_bytes()
# Extract metadata
ts_len = int.from_bytes(data[-8:-4], "little")
n = int.from_bytes(data[-4:], "little")
timestamp = data[-8 - ts_len:-8].decode("ascii")
block = data[:n * n]
# Generate seed and keystream
seed = EMAIL + DATE + timestamp + SALT
mask = keystream(seed, len(block))
# XOR to get transformed data
raw = bytes(b ^ m for b, m in zip(block, mask))
# Convert to NN grid
grid = [list(raw[i * n:(i + 1) * n]) for i in range(n)]
# Extract date components
year, month, day = 2025, 7, 24
# REVERSE TRANSFORM 7: Variable bit rotation
for r in range(n):
for c in range(n):
spin = (year + month + day + r + c) & 7
if spin:
grid[r][c] = rot_right(grid[r][c], spin)
# REVERSE TRANSFORM 6: Even/odd bit swap
for r in range(n):
for c in range(n):
grid[r][c] = bit_flip_pairs(grid[r][c])
# REVERSE TRANSFORM 4: Cyclic shifts
shift = day % n
if shift:
rows = deque(grid)
rows.rotate(-shift)
grid = [list(row) for row in rows]
for r in range(n):
row = deque(grid[r])
row.rotate(-shift)
grid[r] = list(row)
# REVERSE TRANSFORM 3: Subtract constant
# REVERSE TRANSFORM 2: Add constant
add_val = year & 0xFF
sub_val = month
for r in range(n):
for c in range(n):
v = grid[r][c]
v = (v + sub_val) & 0xFF # Undo subtraction
v = (v - add_val) & 0xFF # Undo addition
grid[r][c] = v
# REVERSE TRANSFORM 1: Ring rotation (via column reading)
# Reading column-wise reverses the rotation
buf = bytearray()
for c in range(n):
for r in range(n - 1, -1, -1):
b = grid[r][c]
if b:
buf.append(b)
# Extract text and flag
text = buf.decode("utf-8")
flag = text[text.index("{"):text.index("}") + 1]
return text, flag
if __name__ == "__main__":
poem, flag = decode(FILE)
print(poem)
print('\nFLAG:', flag)

4 Flag Extraction#

Question: Find a way to decrypt the decrypt_me.enc file and submit the flag found in the plaintext output.

Answer:#

Flag: OS{BENDER}


Decryption Results:#

Full Plaintext Content:

[Decrypted poem/message containing the flag]

Flag Format: OS{...}

  • Prefix: OS (OffSec)
  • Content: BENDER
  • Full flag: OS{BENDER}

Flag Location: Embedded within the decrypted plaintext message.


Critical Security Vulnerabilities#

Vulnerability Summary#

#VulnerabilitySeverityImpact
1Base64-encoded “public key”CRITICALNo actual encryption of key material
2Hardcoded salt (PublicSalt)CRITICALPredictable seed component
3No key derivation functionCRITICALDirect seed usage without KDF
4Weak keystream generationCRITICALSimple arithmetic, not cryptographically secure
5Deterministic encryptionHIGHSame input always produces same output
6Static date in public keyHIGHReduces entropy
7Reversible transformationsMEDIUMAll transforms easily reversible
8No authentication/integrity checkMEDIUMNo MAC/HMAC to detect tampering

Detailed Vulnerability Analysis#

1. Public Key is Not a Key#

Issue: The file named publickey.pubkey is simply Base64-encoded data, not a cryptographic public key.

Expected: RSA/ECC public key in PEM/DER format Actual: Base64(24.07.2025|megacorp@quantum.com)

Impact:

  • Anyone can decode and read the “key”
  • No asymmetric cryptography
  • Misleading naming suggests security that doesn’t exist

Fix: Use actual public-key cryptography (RSA 2048+, ECC P-256+)


2. Hardcoded Salt#

Issue: PublicSalt is a constant string, not a random per-encryption salt.

Problem:

  • Same salt for all encryptions
  • Known to attackers (found via reverse engineering)
  • Defeats the purpose of salt (uniqueness)

Impact:

  • Rainbow table attacks possible
  • Pattern analysis across multiple encrypted files
  • No protection against precomputation attacks

Fix: Generate random salt per encryption, store with ciphertext


3. No Key Derivation Function#

Issue: Seed is used directly via simple concatenation:

seed = EMAIL + DATE + TIMESTAMP + SALT

Missing:

  • PBKDF2, Argon2, or scrypt
  • Iteration count (computational hardness)
  • Proper key stretching

Impact:

  • Fast brute-force attempts
  • No computational cost for attacker
  • Weak derivation from password-like inputs

Fix: Implement proper KDF with 100,000+ iterations


4. Weak Keystream Generator#

Issue:

out.append((ord(ch) * 7 + idx) & 0xFF)

Problems:

  • Simple arithmetic operation
  • Not a cryptographically secure PRNG
  • Predictable pattern
  • Linear relationship

Impact:

  • Statistical analysis possible
  • Pattern detection in keystream
  • Not quantum-resistant despite claims

Fix: Use ChaCha20, AES-CTR, or other approved stream cipher


5. Deterministic Encryption#

Issue: Same plaintext + same metadata = same ciphertext

Problem:

  • Timestamp is only variable component
  • If timestamp is known/controlled, encryption is identical

Impact:

  • Replay attacks
  • Ciphertext comparison reveals identical messages
  • ECB-like weaknesses

Fix: Add random IV/nonce to each encryption


Security Recommendations#

Immediate Actions (Critical)#

  1. Implement Real Public-Key Cryptography

    - Use RSA-2048 or ECC P-256 minimum
    - Generate proper key pairs
    - Store private key securely (HSM/key vault)
    - Distribute public key in PEM/DER format
  2. Replace Keystream Generation

    - Use AES-256-GCM or ChaCha20-Poly1305
    - Implement authenticated encryption
    - Use established crypto libraries
  3. Implement Proper KDF

    - Use Argon2id (preferred) or PBKDF2
    - Minimum 100,000 iterations
    - Generate random salt per encryption
  4. Add Authentication

    - Use AEAD (Authenticated Encryption with Associated Data)
    - Add HMAC for integrity
    - Implement MAC-then-encrypt or encrypt-then-MAC

Architecture Recommendations#

Recommended Encryption Scheme:

1. Key Generation:
- Generate random 256-bit master key
- Encrypt master key with RSA-OAEP or ECIES
- Store encrypted master key
2. Per-Message Encryption:
- Generate random nonce/IV
- Derive encryption key: Argon2id(master_key, salt, params)
- Encrypt: ChaCha20-Poly1305(plaintext, key, nonce)
- Output: [nonce || salt || ciphertext || auth_tag]
3. Decryption:
- Extract nonce, salt, ciphertext, auth_tag
- Verify auth_tag first (authenticate before decrypt)
- Derive key using same parameters
- Decrypt and verify

MITRE ATT&CK Mapping#

TacticTechniqueEvidence
DiscoveryT1082 - System Information DiscoveryBinary analysis revealed system architecture
CollectionT1005 - Data from Local SystemEncrypted file analyzed
Credential AccessT1552.001 - Credentials in FilesHardcoded salt in binary
Defense EvasionT1027 - Obfuscated Files or Information7-layer transformation obfuscation

Investigation Objectives - Complete#

#QuestionAnswerStatus
1Decode public key & identify encodingBase64: 24.07.2025|megacorp@quantum.com
2Identify seed calculation componentsEmail, Date, Timestamp, PublicSalt
3Count transformations & explain first 37 transforms: Ring rotation, Add, Subtract
4Decrypt file and extract flagOS{BENDER}

Investigation Status: COMPLETE - ALL OBJECTIVES ACHIEVED


Conclusion#

The Obscurarium Realm’s “unbreakable” and “quantum-proof” encryption system has been completely compromised through systematic reverse engineering and cryptanalysis.

Key Successes:

  1. Public key decoded (Base64)
  2. Seed generation algorithm reverse-engineered
  3. All 7 transformation layers identified and reversed
  4. Keystream generation algorithm replicated
  5. Encrypted file fully decrypted
  6. Flag successfully extracted: OS{BENDER}

Critical Finding: Despite claims of being “quantum-proof,” the system relies on:

  • Weak encoding (Base64) instead of encryption
  • Predictable seed generation
  • Non-cryptographic keystream
  • Reversible transformations without proper cryptographic primitives

The architects’ confidence was misplaced. The system’s complexity (7 transformation layers) provided obfuscation, not security. True security requires:

  • Proven cryptographic algorithms
  • Proper key management
  • Authentication and integrity protection
  • Regular security audits

The Obscuran Key is vulnerable. Immediate remediation is required to protect this critical asset before the adversary exploits these weaknesses.


Report Completed: October 21, 2025
Investigator: MR. Umair
Case Status: CLOSED - System breached, vulnerabilities documented
Recommendation: Complete cryptographic redesign required


“Confidence is no defense against what you’re about to uncover.”

Echo Response - Week 3 Quantum Conundrum - Investigation Report
https://ctf-writeups-webb.vercel.app/posts/events-season1-week3-quantum-conundrum-investigation-report/
Author
Umair Aziz
Published at
2026-04-02
License
CC BY-NC-SA 4.0