3.3 ; COLD CASE
Challenge Description
A memory snapshot was captured from NODE 07 at 2026-03-15T11:48:01Z, one day after the anomaly. Find what was running. Find what it touched. The snapshot uses a proprietary ECHELON format. Standard forensics tools will not parse it.
Files provided: node07_snapshot.mem
Required: access certificate and private key from 3.2 ; FREQUENCY
Overview
The snapshot uses ECHELON Memory Snapshot Format (EMSF). Pages flagged as protected are AES-128-CBC encrypted. The decryption key is derived from the operator certificate recovered in 3.2. The protected page contains the heap of a rogue process, including a file access record whose hash and timestamp form the TOP SECRET portal password.
Step 1: Parse the EMSF Header
The file begins with an 8-byte magic EMSF\x01\x00\x00\x00 followed by a
64-bit Unix timestamp, a 32-bit page count, and 4 reserved bytes. Total header
size is 24 bytes.
import struct
with open("node07_snapshot.mem", "rb") as f:
data = f.read()
magic = data[:8]
ts, page_count, _ = struct.unpack("<QII", data[8:24])
assert magic == b"EMSF\x01\x00\x00\x00"
print(f"Snapshot timestamp : {ts}") # 1773598081 = 2026-03-15T11:48:01Z
print(f"Page count : {page_count}")
Step 2: Parse the Page Directory
Each page directory entry is 20 bytes:
[8 bytes] virtual address (little-endian uint64)
[4 bytes] file offset (little-endian uint32)
[4 bytes] size (little-endian uint32)
[1 byte] flags (0x01=readable ; 0x02=protected)
[3 bytes] padding
PAGEDIR_START = 24
pages = []
for i in range(page_count):
off = PAGEDIR_START + i * 20
va, foff, size, flags = struct.unpack("<QIIB", data[off:off+17])
pages.append((va, foff, size, flags))
print(f"Page {i} : VA=0x{va:016x} flags=0x{flags:02x} size={size}")
Three pages are present. Page 0 (process list) and page 1 (string table) are
readable. Page 2 at 0x00007f3a40000000 is flagged 0x03 (readable and
protected), this is the target.
Reading the unprotected pages first establishes context. Page 0 shows the
process list at snapshot time. PID 892 (ECORE.SVC.23a) is annotated as an
anomaly. Page 1 confirms its path as /tmp/.ecore/ECORE.SVC.23a, not a
registered echelon service.
Step 3: Derive the Decryption Key from the Certificate
The protected page is AES-128-CBC encrypted. The key and IV are both derived from the operator certificate DER bytes via SHA-256:
import hashlib, base64
lines = open("node07_access.crt").read().splitlines()
b64 = "".join(l for l in lines if not l.startswith("-----"))
cert_der = base64.b64decode(b64)
print(len(cert_der)) # 429
digest = hashlib.sha256(cert_der).digest()
mem_key = digest[:16]
mem_iv = digest[16:32]
Strip the header and footer lines by filtering rather than slicing, the slice
approach breaks depending on whether the file has a trailing newline. The
len(cert_der) check is a useful sanity test before proceeding.
The certificate is the access cert recovered from calibration report B in 3.2 ; FREQUENCY. The private key from that same report is not needed here, only the public certificate is used for key derivation.
Step 4: Decrypt the Protected Page
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
for va, foff, size, flags in pages:
page_data = data[foff:foff+size]
if flags & 0x02:
pt = unpad(AES.new(mem_key, AES.MODE_CBC, mem_iv).decrypt(page_data), 16)
print(pt.rstrip(b"\x00").decode())
Step 5: Extract the Artifact
The decrypted page is the heap region of ECORE.SVC.23a. It contains a
HEAP.ARTIFACT ; FILE.ACCESS.RECORD block:
PATH ; /opt/echelon/data/archive/relay_config.enc
OPERATION ; READ
TIMESTAMP ; 2026-03-15T11:44:09Z
SIZE ; 18432
HASH.SHA1 ; a7f3c2d94e1b80563b92a7d0f4c1e658
HASH.MD5 ; 4d7a2f9e1c3b8056a7f3d2c94e1b8056
ACCESS.CERT.KEY ; 8e828c782fd0d3c1b95ac0da6853f75b
The ACCESS.CERT.KEY field is the SHA-256 derived key used to authenticate
access to this node's memory, the same value computed in Step 3 to decrypt
this page. Keep it, it is one of three inputs to the final challenge.
The TOP SECRET portal gate shows the expected format. The values needed to
construct the password are in the HASH.SHA1 and TIMESTAMP fields of the
file access record.
The page also contains a HEAP.ARTIFACT ; NETWORK.SOCKET block, which has the flag:
REMOTE.ADDR ; 10.7.0.1:4433
PROTOCOL ; ECP/1.2
STATE ; ESTABLISHED
SINCE ; 2026-03-15T09:22:44Z
NOTE ; Process loaded from /tmp/.ecore/ ; not a registered echelon service
NOTE ; File accessed 3 times in 47 minutes before system reset
FLAG ; ECHELON{mem0ry_never_f0rgets}
Key Takeaways
Memory forensics consistently recovers artifacts that running processes believed were transient. Heap allocations persist until overwritten; process strings, file paths, and access records all survive a system reset if a snapshot is taken before the memory is reclaimed. Tools like Volatility (https://volatilityfoundation.org) apply this same principle to full OS memory images, recovering process trees, open file handles, network sockets, and injected code from raw dumps.
Flag
ECHELON{mem0ry_never_f0rgets}