The challenge
"Every compiler signs its work. Compare the runtime and linker fingerprints across builds and name the toolchain — attribute this binary to its maker."
Binary is cumulative: 324 questions, 12 per day for Days 1–27, all on one evidence.zip. Of the 12 Day 27 fields, six were familiar in form (the two members' SHA-256s and the shared HCFG config's campaign, domain, mutex, and URL, "require their config objects to be byte-for-byte equal"). Six were new, each picking one build by name:
| answer_id | Question | Format |
|---|---|---|
d27_, d27_ |
"Use the unique d27-- member whose basename ends gcc.elf [tcc.elf]. Classify final bytes by magic and parsed container: elf … pe … pe_cli … jar … wasm … neko_bytecode" | enum |
d27_, d27_ |
"… Read the ELF e_machine field and submit its unsigned base-10 numeric value (for example, do not substitute an architecture label)." | base-10 integer |
d27_, d27_ |
"… Scan backward from the end of the member for literal HCFG magic and accept the first CRC32-valid decoded JSON record …" | exact text |
The Time Trial asked the same 324; the Mastery asked them once per set (11 sets, 3,564 answers).
Reading the prompt: what it said we'd need
| Clue | What it pointed to | What I did about it |
|---|---|---|
| "Every compiler signs its work" | Toolchain fingerprints in the binary (runtime, linker, .-style strings) |
Two builds of one program, named by toolchain: d27- and d27- |
| "Compare … across builds" | Questions about each build separately | The six new fields pick a build by "basename ends gcc.elf / tcc.elf"; the solver's core only knew variant- names, hence the 6 left open |
| "name the toolchain" | Identify the compiler from fingerprints | No question asked for it; the member names already carry the toolchain |
| "attribute this binary to its maker" | Tie each build to its config | Per-build HCFG reads (campaign, domain), plus the shared-config fields that require both builds to agree |
| "Compiler Says What" (title) | Compiler attribution | Confirmed the reading |
Safety
Static analysis only. Nothing was executed. The ELF members were read as bytes: header fields, then a backward scan for the HCFG record and its CRC32 check. No sample was run, loaded, or debugged. For this write-up only the question list, the solver's record of accepted answers, the request log, and the helper's notes were read. The archives stayed on our Kali VM. Indicators below are defanged.
What was in the files
- Single Solve:
evidence.zip, 35,900,240 bytes, password-protected members covering Days 1–27. Today's members are two ELF64 little-endian builds of one program:d27--sample-gcc.elf(108,155 bytes) andd27--sample-tcc.elf(462,379 bytes), both withe_machine62 (x86-64). - One raw HCFG record near the end of each build (gcc at offset 107,776, tcc at 462,000; version 1, XOR key
0xc1), and the two configs are identical (defanged): campaignBR27-000, domainnode-000[.]day27[.]example[.]invalid, mutexGlobal\HuntressBR27_000, URLhxxps://node-000[.]day27[.]example[.]invalid/api/BR27-000. - Accepted Day 27 role values: both formats
elf, both machines62, gcc campaignBR27-000, gcc domainnode-000[.]day27[.]example[.]invalid. - Time Trial:
evidence.zip, 36,035,463 bytes, the same two-build template with a randomised config (campaignBR27-2BB2…); formats and machines againelf/62. - Mastery: eleven archives, 35.88 to 36.04 MB each, streamed. Every set had the same gcc/tcc pair with
elf/62and its own config (eleven different campaigns and domains). No new toolchain appeared in any timed set.
Single Solve
The solver: 318 sent, 6 open
started_at 2026-10-27 09:01:38.531 ET (solver)
deadline none (Single Solve)
answers 226 core (accepted, remaining 98), then 92 add-on answers (accepted, remaining 6)
timings start 438 ms, artifact 1767 ms, solve 1381 ms, submit phase 1740 ms
result not CORRECT: 6 questions unanswered; timed modes not started
The solver's core already answered the two SHA-256s and the four shared config fields; it had no rule for a dNN--sample-<role>.elf member, so the six per-build fields were left. Leaving them open was right: nothing was guessed.
The add-on (helper)
The helper wrote a new add-on module (days ≥ 27), in a separate copy of the solver:
- Matches dNN_analysis_<role>_(format|machine|config_<key>). The member is chosen by the question's own "basename ends X" phrase, else a -<role>.<ext> tail. No member for the role: skipped; two: raises.
- Roles other modules own (vulnerable/corrected, loader/plugin, stripped/symbolized/compact/direct) are skipped, so it can't claim an older day's field.
- Format from magic plus a parsed container (pe_cli needs a CLR directory and a BSJB metadata root); machine is the ELF e_machine or PE COFF Machine, in base 10; config is the last CRC32-valid HCFG record in file order (a backward scan), raw first, then Base64.
The first choices were elf; 62 (the form already confirmed for this field type); and gcc config values equal to the already-accepted shared ones, to be sent one at a time without resending a rejected value. Offline on the separate copy: coverage 324 of 324, the 318 accepted answers reproduced with 0 mismatches, unit tests 7 of 7. The helper then ran the separate copy, which reconnected to the solver's open attempt and sent only the six:
started_at 2026-10-27 09:01:38.531 ET (solver's attempt; reconnected 09:05:24)
answers 6 (gcc/tcc format elf, gcc/tcc machine 62, gcc campaign and domain)
result CORRECT flag 612e1b3a…02cf (09:05:29.561)
All six were accepted on the first try; no value was rejected.
Time Trial
CORRECT on the first attempt, ranked (unique_attempts_remaining: 63). Day 26's slip (a by-hand timed run started without the ranked clock) didn't recur.
started_at 2026-10-27 09:05:44.342 ET
deadline 2026-10-27 09:07:04.342 ET (80 s)
answers 324
start 220 ms after started_at
artifact 2638 ms after started_at (36.0 MB)
solve 3604 ms after started_at (966 ms)
submit 4468 ms after started_at
result CORRECT flag c27e0263…01e5 (09:05:48.177)
Mastery
CORRECT on the first attempt, ranked (streamed with 3 solve workers; 11 sets, 725 s clock, unique_attempts_remaining: 15).
started_at 2026-10-27 09:05:54.545 ET
deadline 2026-10-27 09:17:59.545 ET (725 s)
answers 3,564 (11 sets × 324)
start 414 ms after started_at
artifact 7558 ms after started_at (11 × ~36 MB, streamed; last download done)
solve 8978 ms after started_at
submit 10593 ms after started_at
result CORRECT flag abd6db37…89f0 (09:06:03.918)
The helper's notes give 09:06:05, the time the reply was logged; the Game Master's solved_by.at is 09:06:03.918.
Checks and install
All after the three CORRECTs, on the separate copy:
- Unit tests: 41 passed.
- Re-solving the 133 saved Binary sets with the fast path off: the old and new solvers each had 1 error (Day 1's known manifest error, same message); 129 identical, 3 gained answers only (today's Single +6, TT +6, Mastery +66, all d27_analysis_ fields), no changed answer.
- A regression check against every answer the Game Master had already accepted: they agree on 324 / 324 / 3,564 (apart from Day 1's known path-only error, as on Days 24 and 26).
- A streamed replay of 52 saved Mastery attempts: 0 errors, identical to the whole-solve results.
The add-on went into the solver at 09:18:58 ET, with live coverage 324 of 324.
Time to solve
All three modes were solved by 09:06:03 ET, 6 min 3 s after release (4 min 25 s from the first start request on this lane). The Single Solve needed the new add-on for its last 6 answers; the Time Trial and Mastery were both ranked and each went through on the first submit.
Takeaways
- Leaving fields open beats guessing. The solver sent the 318 it was sure of and stopped on 6 with no rule; the helper only had to add those 6, all accepted first try.
- Pick the member the way the question says. Today's fields named their build by "basename ends gcc.elf"; the add-on uses the question's own phrase first, so a renamed or reordered member can't confuse it.
- Writing for
day >= Nkeeps paying, and so does skipping other days' roles. The add-on skips roles that other modules own and days that have no matching member (the Day 26 lesson, when an add-on claimed a JAR day and crashed the Single). - Ask for the ranked clock on every by-hand timed run. Both ranked runs were first-try and ranked today, so no ranked pass is owed for Day 27 (Day 26's slip cost a second pass).
- The prompt promised more than the questions asked. "Name the toolchain" from runtime and linker fingerprints needed nothing: the member names gave it, and the fields asked only format, machine, and config.