← All writeups

Forensics

Catch the Criminal — CDDC2026

Category: Forensics Flag: CDDC2026{times_square_260420_1930}

Challenge

Defender, through your analysis, you identified the confidential file that Alex, a former employee of Company P, leaked before leaving the company. Intelligence indicates that he plans to deliver the leaked file to the client, and you must identify the rendezvous.

Artifact: Catch the criminal.zip containing Catch the criminal.ad1 (≈321 MB FTK Imager AD1 logical image) and its .ad1.txt manifest.

Required answers:

  1. Where is the rendezvous? (lowercase, spaces → _)
  2. When is the rendezvous? (YYMMDD_HHMM)

Recon — what's in the AD1

The .ad1.txt manifest reveals the acquisition deliberately scoped to:

The interesting evidence is going to live inside the messaging app + AI app data — not the OS.

Step 1 — Extract the AD1

AD1 is AccessData's proprietary "Custom Content Image" format (ADSEGMENTEDFILE → ADLOGICALIMAGE). FTK Imager isn't installed and 7z doesn't speak it. Used pcbje/pyad1 with two small patches:

  1. __enter__ pops paths[0] before _ReadHeader calls _ReadLastFrom(-372) on paths[-1] — empty when there's a single segment. Cache self.last_path = self.paths[-1] before popping.
  2. Sanitize Windows-illegal characters (:|*?<>") in folder/file names from the NTFS namespace (e.g. Catch the criminal.E01:NONAME [NTFS]).
with reader.AD1Reader(ad1_path) as ad1:
    for item_type, folder, filename, metadata, content in ad1:
        ...  # write files / mkdir for dirs

Result: ~574 MB extracted to extracted/Catch the criminal.E01_NONAME [NTFS]/[root]/....

The iterator throws Exception('Incomplete read') at the very end (trailing metadata block), but by then all file content has been written.

Step 2 — Recover the Wire conversation

Wire stores messages in Chromium IndexedDB (LevelDB): AppData\Roaming\Wire\IndexedDB\https_app.wire.com_0.indexeddb.leveldb\000003.log

Wire's payload is end-to-end encrypted at the protocol layer, but the decrypted plaintext is cached locally as UTF-16LE strings in the LevelDB log. Quick extract:

data = open(log_path, 'rb').read()
for m in re.finditer(rb'(?:[\x20-\x7e]\x00){15,}', data):
    print(m.group().decode('utf-16le', errors='ignore'))

Sorted by timestamp, the conversation between Alex and the buyer (2026-04-16):

Time (UTC) Message
11:53:44 "Well done. I knew you were the right choice. Now for the final step. To keep things secure, it's best we meet in person to hand over the storage device. Have you picked a spot?"
11:55:38 "I wanted to avoid any radar from the security team, so I consulted an AI to find a high-traffic location where I could easily blend in. It gave me a few recommendations, and I've made my choice."
11:57:04 "Using AI for that? You're even sharper than I thought. Send me the details later. What time are we talking? If it's too late, it might raise some red flags."
11:58:16 "This Friday is my last day. I think it's best to meet right after I finish packing my things and clear out of the office for good."
12:00:02 "See you then. The remaining 9 BTC will be transferred to your wallet the moment I've verified the files."

The message doesn't name the spot — it points us at the AI chat history instead.

Step 3 — The AI consult (ChatGPT Desktop)

AppData\Local\Packages\OpenAI.ChatGPT-Desktop_2p2nqsd0c76g0\LocalCache\Roaming\ChatGPT\IndexedDB\https_chatgpt.com_0.indexeddb.leveldb\000003.log

Plaintext strings reveal a conversation titled "Famous Crowded Places USA":

text"0Where is a famous and crowded place in America?
text"|There should be so many people that it's hard for someone to see who's important, is there a lot of people in Times Square?

Alex's chosen rendezvous: Times Square.

Step 4 — The date/time

A bonus image artifact shipped with the challenge gives the meeting time directly: 2026-04-20 19:30260420_1930.

(Consistent with the Wire conversation: Friday Apr 17 was Alex's last day; the rendezvous follows the next Monday evening.)

Flag

Part Value
Location times_square
Datetime 260420_1930

CDDC2026{times_square_260420_1930}

Notes / lessons