The challenge
The prompt opens with "One binary is a clue; a campaign is a story." It then asks for the loader, library, and config graph to be rebuilt across the whole set, mapping the operation end to end.
Binary is cumulative: 420 questions, 14 per day for Days 1–30, all on one evidence.zip. Day 30's 14 were three SHA-256s of the new members plus eleven analysis fields:
| answer_id | Question (shape) | Format |
|---|---|---|
d30_ … _ |
SHA-256 of each d30- member in central-directory order |
64 lowercase hex |
d30_ |
The member whose basename ends loader. / library. / config.: classify the final bytes by magic and parsed container |
enum: elf, pe, pe_, jar, wasm, neko_ |
d30_ |
loader.'s decoded HGRF record, JSON property graph., "after confirming all three canonical campaign graphs match when this_role is omitted" |
exact text |
d30_ |
The same property from config.'s HGRF record |
exact text |
The HGRF questions spell out the record: scan backward from the end of the Neko member for the unique CRC32-valid record, with the same 12-byte layout as the HCFG records from earlier days (byte-4 version, byte-5 XOR key, little-endian length and CRC32, XOR-encoded UTF-8 JSON).
The Time Trial asked the same 420; the Mastery asked them once per delivery (14 deliveries, 5,880 answers).
Reading the prompt: what it said we'd need
| Clue | What it pointed to | What I did about it |
|---|---|---|
| "a campaign is a story" | Several samples that only make sense together | Three Neko members (loader, library, config) each carry a copy of one JSON "campaign graph" |
| "Reconstruct the loader, library, and config graph" | Nodes and edges between the three roles | The graph JSON has nodes, edges, load_, config{…}, and this_; the questions only asked for config strings |
| "across the whole set" | Compare the copies, don't trust one | The helper checked that the three graphs are equal apart from this_, as the loader questions require |
| "map the operation end to end" | A full read of the campaign | Not needed beyond the config fields; no question asked for the edges or load order |
| "Classify final bytes by magic" (question text) | A new container type | Magic NEKO: the enum's neko_ is the only token for it |
| "the same 12-byte layout as HCFG" (question text) | Reuse the HCFG decoder with a new magic | HGRF records decode exactly like HCFG; only the magic and the JSON shape are new |
Safety
Static analysis only. Nothing was executed. The members were read as bytes: magic, the trailing HGRF record, its CRC32 check, and the XOR-decoded JSON. No Neko VM was installed and no sample was run or loaded. For this write-up only the helper's notes, the plug-in, the saved answer and timing records, the archive member lists, and the Game Master log were read. The archives stayed on our Kali VM. Indicators below are defanged.
What was in the files
- Single Solve, Day 30 members:
d30--sample-loader.n(20,880 bytes),d30--sample-library.n(20,890), andd30--sample-config.n(20,916). All three are Neko bytecode (magicNEKO). - One HGRF record near the end of each. The decoded JSON uses schema
huntress.binary.campaign_graph.v1withnodes,edges,load_order,config{…}, andthis_role. The three graphs are equal apart fromthis_role. - The config values (the same in
loader.nandconfig.n): campaignBR30-000, domaincampaign-000[.]day30[.]example[.]invalid, mutexGlobal\HuntressBR30-000, and URLhxxps://campaign-000[.]day30[.]example[.]invalid/stage/BR30-000. - Time Trial and Mastery: the same template with different values. Every archive (1 for the Time Trial, 14 for the Mastery) has 45 members, including the same three
d30--sample-*.nnames. Their sizes differ only by a few bytes between archives (loader 20,921–20,926 bytes), which fits different config strings in the same layout.
Single Solve
The automated solver: 410 sent, 10 open
started_at 09:01:16.8 ET (started by the solver)
deadline none (Single Solve)
answers 253 core (accepted, remaining 167), then 157 plug-in answers (accepted, remaining 10)
timings start 589 ms, artifact 3,612 ms, solve 2,186 ms, submit phase 1,748 ms
result not CORRECT: 10 questions unanswered, no rejected values; timed modes not started
The 10 open ids were all new Day 30 fields: the loader and config-capsule formats and the eight HGRF config strings. The older Day 27 role-builds plug-in skips the loader role (another plug-in owns it) and its field pattern doesn't match config_capsule_format, so neither format was answered; nothing knew about HGRF. The library format, which that plug-in does cover, was already accepted. Leaving the 10 open was right: nothing was guessed.
The plug-in (Claude helper agent)
The helper wrote a new plug-in for days ≥ 30 and tested it on a staging copy of the solver:
- Member from the question text: "basename ends X" or "Use X's decoded HGRF".
- Record: the last CRC32-valid HGRF record in the member ("scanning backward from the end"), decoded with the HCFG layout.
- Answer: the string at graph.<path> named in the question. The _format fields reuse the Day 27 plug-in's container classifier.
- Archive choice as on earlier days: one archive given (streamed Mastery) → use it; otherwise by set or delivery N:.
Staged test: coverage 420 of 420, and every answer already accepted was reproduced.
Formats: neko_bytecode. Campaign, domain, and URL: the decoded JSON string as stored. The one judgement call was the mutex: first the decoded string with one backslash (the form accepted for every HCFG mutex since Day 3), and the JSON-escaped form with two backslashes only if that was rejected.
The helper sent the 10 on the solver's open attempt:
reconnected to the solver's attempt 09:06:04 ET
answers 10 (the plug-in's)
start 343 ms
artifact 2,488 ms
solve 3,366 ms
submit 852 ms
TOTAL 7,059 ms
result CORRECT flag c1d440eb…b93e (09:06:10.465 ET)
The one-backslash mutex was accepted; the second form was never sent.
Time Trial
CORRECT on the first attempt, ranked (variant_fresh: true).
started_at 2026-10-30 09:06:46.366 ET
deadline 2026-10-30 09:08:06.366 ET (80 s)
answers 420
artifact +1.17 s after started_at
solve +2.08 s
submit +3.25 s (TOTAL 3.8 s, solve 0.9 s)
result CORRECT flag 4e3decd9…f48b (09:06:48.718 ET)
Mastery
CORRECT on the first attempt, ranked (streamed, 14 deliveries).
started_at 2026-10-30 09:06:56.679 ET
deadline 2026-10-30 09:18:01.679 ET (665 s)
answers 5,880 (14 deliveries × 420)
downloads 14 streamed, last at +4.98 s after started_at
solve +8.47 s
submit +10.12 s (TOTAL 11.4 s, solve 3.5 s)
result CORRECT flag 445c09e4…ad76 (09:07:05.646 ET)
Install
At 09:08 the helper added one new file, the plug-in, to the live solver. No existing file changed, so removing that file rolls it back. Live coverage afterwards: 420 of 420. The solver's fast path still has no stored shortcut for this profile, so the Binary solve stays a full solve, as since Day 24.
Time to solve
All three modes were solved by 09:07:05.6 ET, 7 min 5.6 s after release and 5 min 48.8 s after the solver's first start; most of that was writing the plug-in for the 10 open fields. Both timed modes were ranked and went through on the first submit, with no rejected value on any mode.
Takeaways
- The question text was the spec again. It named the magic, the scan direction, the 12-byte layout, and the JSON path. The plug-in reads the member and the path from the text instead of hard-coding them.
- A new magic over an old layout is a small change. HGRF is HCFG with a new magic and a richer JSON payload, so the existing decoder logic carried over.
- Leaving fields open beats guessing. The solver sent the 410 it was sure of; the helper added only the 10.
- Settle form questions before sending. The mutex had two plausible forms; ranking them, with the form accepted since Day 3 first, meant one submit and no rejected value.
- New files only make installs cheap. One added file, no edits, so the rollback is a single delete.