← All writeups

P2P

Mystery Inc Batch Clue Sheet

Flag: P2P{b4tch_th3_b0r1ng_stuff}

Challenge

The clue ledger is full of repetitive suspects on two rows each, and only one pair actually matters. Write the smallest clean script that filters the noise, decodes the confirmed hit, and prints the flag.

File: 1780126805_batch_candidates.txt (60,004 lines, ~20,000 suspects)

Recon

The file header spelled out the format:

# Mystery Inc batch clue sheet
# Each suspect uses two rows: verdict on line 1, clue on line 2.
# Confirmed clues are base64 on the clue line (encoding=base64 on line 1).
# Script the filter — do not read twenty thousand suspects by hand.

So every suspect occupies two rows:

suspect=ghost-clown mask=half-on score=12 sheet=A1 verdict=discard
clue=ticket-stub-00001 analyst=velma

The decode rule: a clue is base64-encoded only when its verdict line carries encoding=base64, and the header promised exactly one such pair matters.

Finding the needle

Rather than read 20k suspects by hand, filter on the markers:

$ grep -oE 'verdict=[a-z]+' batch_candidates.txt | sort | uniq -c
      1 verdict=confirm
  19999 verdict=discard

$ grep -n 'verdict=confirm' batch_candidates.txt
45003:suspect=carnival-ringleader mask=clean score=99 sheet=B50 verdict=confirm encoding=base64

Exactly one suspect breaks the pattern — carnival-ringleader on line 45003, the only one tagged verdict=confirm encoding=base64. Its clue sits on the next line (45004):

clue=UDJQe2I0dGNoX3RoM19iMHIxbmdfc3R1ZmZ9 analyst=fred

Decode

$ echo 'UDJQe2I0dGNoX3RoM19iMHIxbmdfc3R1ZmZ9' | base64 -d
P2P{b4tch_th3_b0r1ng_stuff}

Gotcha: the clue line has a trailing analyst=fred. Feeding the whole line into base64 -d triggers an invalid input warning — you must extract just the token after clue= up to the first space.

Solution script

#!/usr/bin/env python3
"""Find the one confirmed suspect and decode its base64 clue into the flag."""
import base64, re, sys

lines = open("batch_candidates.txt").read().splitlines()
for i, line in enumerate(lines):
    if "verdict=confirm" in line and "encoding=base64" in line:
        token = re.search(r"clue=(\S+)", lines[i + 1]).group(1)
        print(base64.b64decode(token).decode())
        sys.exit(0)
$ python3 solve.py
P2P{b4tch_th3_b0r1ng_stuff}

re.search(r"clue=(\S+)") grabs only the base64 token and ignores the trailing analyst=fred, sidestepping the invalid input gotcha entirely.

Takeaways