zwesty
Write-ups / Day 10 / Metadata
Day 10 · Sat, Oct 10 · Metadata

Where Do We Begin?

Prey slaughtered

PE optional header (AddressOfEntryPoint as an RVA), checking the entry point against the section table, answer formatting (zero-padding to the field's width), reusing a compounding solver

STTMClaude Homebase Both

Flags are shortened to their first 8 and last 4 characters because they're unique per team.

Challenge ID
metadata-forensics-day-10-where-do-we-begin (+ /time_trial, /mastery)
Solved
2026-10-10: Single Solve CORRECT on the second submit (the first was incorrect), Time Trial CORRECT, Mastery CORRECT; 8 min 4 s from the first start to Mastery CORRECT
Player
Zwesty (solo), with Claude Code (Opus 5.5)

The challenge

"Architecture tells you whether a binary can run; its entry point tells you where execution begins. Map the start addresses and catch the report that is lying."

One question about telemetry-agent-001.exe inside metadata-day-10-evidence.zip.

answer_id Question Format
d09-pe-001-pe-address-of-entry-point-rva-hex "Determine pe.address_of_entry_point_rva_hex for telemetry-agent-001.exe." "lowercase hexadecimal with a 0x prefix and no explanatory text", trimmed

The answer ID starts with d09-, the same prefix as Day 9's PE field, even though this is Day 10. It looks like the prefix follows the day the PE file type was introduced, but nothing confirms that. The format says nothing about padding, which is what cost a submit (see Single Solve).

Reading the prompt: what it said we'd need

Clue What it pointed to What I did about it
"Architecture tells you whether a binary can run" Day 9's COFF Machine field Reused Day 9's check unchanged: MZ, e_lfanew, PE\0\0, then Machine. A file that fails it is not a PE and answers none
"its entry point tells you where execution begins" The optional header's AddressOfEntryPoint, an RVA (an address relative to where the image loads), not a file offset Read the u32 at e_lfanew + 24 + 16, which is the same offset in PE32 and PE32+
"Map the start addresses" One entry point per binary, possibly several files The Single Solve asked about one file only. The solver handles any number of PE fields by name
"catch the report that is lying" Some stated value that the bytes contradict No separate question asked for this in the Single Solve. I checked that the entry point falls inside .text, and nothing in the file disagreed. The files I have don't show what the "report" was meant to be, so I can't say more
"lowercase hexadecimal with a 0x prefix" Spelling of the answer Sent the bare value first (rejected), then padded to 8 digits (accepted)

Safety

  • The artifact is a Windows executable (a Go binary). Everything was static: the solver reads bytes with struct and never runs, loads, or imports a challenge file.
  • The artifacts stayed on our Kali VM; none were copied to a Windows machine.

What was in the files

telemetry-agent-001.exe is a PE32 (Intel i386) Go binary. Its optional-header AddressOfEntryPoint is 0x65bd0, and that RVA sits inside the .text section, which is where code should start. Nothing else in the file contradicted it.

The rest of the zip's members weren't recorded, so I can't say whether it also held earlier days' files or decoys, or a "report" file that the prompt's last sentence refers to. The Time Trial log shows one answer sent, so it asked the same single field with new values; Mastery's log shows two answers sent. The timed question text wasn't saved, so I can't confirm the exact wording or set count beyond that.

Single Solve

Our solver wraps Day 9's, which already wraps Days 1–8. It adds entry_point_rva(): it first requires Day 9's coff_machine() to accept the file as a real PE, then reads the optional header's size (the field at e_lfanew + 20). If that size is too small or the header runs past the end of the file, the answer is none. Otherwise it returns the AddressOfEntryPoint u32. Any question ID ending in pe-address-of-entry-point-rva-hex gets that value as 0x plus 8 lowercase hex digits. Every other question falls through to Day 9's code. Run on its own, the solver lists every zip member as "PE machine …, entry …" or "not a PE". Our shared Game Master client handles the requests.

Submit 1, 0x65bd0: incorrect. The value was right but the spelling wasn't.

Submit 2, 0x00065bd0: CORRECT (249c5ce7…e8ac). The reasoning came from Day 9, where the u16 Machine field was accepted as 0x014c (four digits, with a leading zero). The rule that fits both days is header fields are zero-padded to their width, so a u32 gets 8 hex digits.

Its tests (4, all pass): - synthetic PE32 and PE32+ headers return the right entry point; - decoys return nothing: a shell script, an ELF, and a PE whose optional-header size is 0; - the real Single Solve answers exactly 0x00065bd0; - Day 9's real question set still gets all 13 answers, including 0x014c.

Time Trial

CORRECT on the first attempt. The status reported only 1 unique attempt remaining before the run, so there was no room for a second try. The deadline was 8 s after started_at.

started_at  2026-10-10T14:29:09.698Z
deadline    2026-10-10T14:29:17.698Z   (8 s)
answers     1
start       489 ms
artifact    485 ms
solve         6 ms
submit     1089 ms
TOTAL      2.07 s
result      CORRECT   flag 008c4a67…9f2d

Mastery

CORRECT on the first attempt, also with only 1 unique attempt remaining. The deadline was 11 s after started_at.

started_at  2026-10-10T14:29:13.733Z
deadline    2026-10-10T14:29:24.733Z   (11 s)
answers     2   (from the request log)
start       423 ms
artifact    405 ms
solve        15 ms
submit      930 ms
TOTAL      1.77 s
result      CORRECT   flag c1968c6e…ff69

Time to solve

All three modes were solved in 8 min 4 s, from the Single Solve start at 14:21:11 UTC to the Mastery CORRECT at 14:29:15 UTC. The Single Solve's first submit (unpadded) was incorrect and the second went CORRECT at 14:28:20; the Time Trial (2.07 s) and Mastery (1.77 s) each went through on the first submit.

Takeaways

  • The entry point is an RVA, not a file offset. It's where the loader jumps after mapping the image, so it should land inside an executable section like .text. Checking that is a quick sanity test on any PE.
  • "Lowercase hex with a 0x prefix" left out the padding rule. The value was right on the first submit and still rejected. Day 9's accepted answer showed the convention: pad a header field to its width (u16 → 4 digits, u32 → 8). The solver now does this, and a test pins it.
  • Compounding solvers pay off again: Day 10 needed one new function on top of Day 9's PE checks, and a test proves Day 9 still answers.
  • Not everything in the prompt became a question. "Catch the report that is lying" didn't appear as its own field in the Single Solve. I've noted it rather than guessed at it.