The challenge
"Two builds, one fix. Diff the vulnerable function against its corrected twin and pinpoint exactly what changed — then prove the old one was really broken."
Binary is cumulative: 288 questions, 12 per day for Days 1–24, all on one evidence.zip. The 12 Day 24 fields:
| answer_id | Question (short) | Format |
|---|---|---|
d24_, _ |
SHA-256 of d24- members 1 and 2, in ZIP central-directory order |
64 lowercase hex |
d24_, d24_ |
Classify the member ending vulnerable. / corrected. by magic and container |
enum: elf, pe, pe_, jar, wasm, neko_ |
d24_, _, _, _ |
"Decode both d24-- role members and require their config objects to be byte-for-byte equal", then the HCFG JSON fields | exact text |
d24_, _, _, _ |
The same HCFG fields, from the corrected. member only |
exact text |
The HCFG rule in the question text: parse every class file's constant pool; Base64-decode every Base64-alphabet UTF-8 constant of at least 80 characters; take the first CRC32-valid HCFG JSON record (HCFG, version byte, XOR key byte, payload length, CRC32). Time Trial asked the same 288; Mastery asked them once per set (8 sets, 2,304 answers).
Reading the prompt: what it said we'd need
| Clue | What it pointed to | What I did about it |
|---|---|---|
| "Two builds" | Two members: d24- and d24- |
Both are JARs: format jar for each |
| "one fix … Diff the vulnerable function against its corrected twin" | A bytecode diff of one method | None of the 12 Day 24 questions asked for the diff. The answers come from the containers and the embedded config |
| "prove the old one was really broken" | Show the vulnerable behaviour | Not asked either. Nothing to run |
| "require their config objects to be byte-for-byte equal" (question text) | Both builds carry the same HCFG config | The solver's core already decodes both and checks they match; those 4 fields were covered |
| "Use the unique d24-- member whose basename ends corrected.jar" (question text) | The same config from one member | The corrected build's config must equal the accepted common one, so the common values were the first choice |
| "jar for a ZIP/JAR with classfiles" (format text) | Format by container | A ZIP whose entries include . files → jar |
Safety
Static analysis only. Nothing was executed. The JARs were opened as ZIP files and their class files read as bytes (Base64 runs, then the HCFG scan); no Java runtime was started. The archives stayed on our Kali VM.
What was in the files
- Single Solve:
evidence.zip, 35,684,100 bytes, password-protected members covering Days 1–24. Today's members ared24--sample-vulnerable.jar(4,054 bytes, member 1) andd24--sample-corrected.jar(4,422 bytes, member 2). SHA-256:7a4706e9…d922and38723bc7…7863. - The HCFG record decoded to a synthetic config (defanged), the same in both builds: campaign
BR24-000, domainnode-000[.]day24[.]example[.]invalid, mutexGlobal\HuntressBR24_000, URLhxxps://node-000[.]day24[.]example[.]invalid/api/BR24-000. - Time Trial: one
evidence.zipof 35,818,671 bytes. Mastery: eight, 35.66 to 35.79 MB each. Same template with different values; the whole solve ran unchanged on all of them once the add-on was in.
Single Solve
The solver's batches: accepted, 6 remaining
The solver reported coverage 282 of 288: the two *_format fields and the four corrected_config_* fields had no answer. It sent the core batch (205, accepted, 83 remaining) and the add-on batch (77, accepted, 6 remaining). With questions it couldn't answer, it stopped there and left Binary, timed modes included, for Claude.
started_at 2026-10-24T13:01:09.954Z (solver)
deadline none (Single Solve)
answers 205 core (accepted, remaining 83), then 77 add-on (accepted, remaining 6)
start 383 ms
artifact 2124 ms (35.7 MB)
solve 1037 ms
submit 1749 ms (core 459, add-ons 1288)
TOTAL 5293 ms
result accepted, remaining 6; solver stopped Binary; timed modes not started
The last 6 (Claude)
The accepted d24_analysis_config_* values already required both builds' configs to be byte-for-byte equal. So the corrected build's config had to be the same. The answers chosen:
- both *_format: jar (both members are ZIPs with class files);
- corrected_config_campaign BR24-000, _domain node-000.day24.example.invalid, _mutex Global\HuntressBR24_000, _url the accepted common URL.
All were accepted on the first try, so no other value was sent.
started_at 2026-10-24T13:01:09.954Z (same attempt, finished by Claude at 13:02:37)
answers 6
result CORRECT (13:02:38) flag not recorded: see below
The Single Solve flag isn't on file. Our request log keeps only the first ~4,000 characters of each reply, and this reply's flag came after the cut; the submit wasn't saved to a file. The CORRECT result itself is in the log.
The add-on (Claude)
A new add-on module answers the six fields for every Binary day from 24 on:
- dNN_analysis_{vulnerable,corrected}_format: jar when the member is a ZIP whose entries include .class files; anything else raises.
- dNN_analysis_corrected_config_*: from the corrected JAR only. It reads every class file, Base64-decodes every Base64-alphabet run of at least 80 characters, and asks the shared HCFG reader for CRC32-valid records; the first one's JSON config supplies the value.
- Safe for streamed Masteries: when a Mastery archive is handed over on its own, it uses that one archive; otherwise it picks by set or by the delivery N: name.
One honest difference: the question says "parse every constant pool", while the add-on scans the class bytes for Base64 runs. That finds the same constants here (a Java constant-pool string is stored as plain UTF-8 bytes), and every set's corrected-config answers were accepted alongside the core's common config.
It was built in a separate copy (the solver wasn't touched while it was running), and both timed modes ran from there.
Time Trial
CORRECT on the first attempt, ranked (80 s clock), from the separate copy.
started_at 2026-10-24T13:03:21.520Z
deadline 2026-10-24T13:04:41.520Z (80 s)
answers 288
start 154 ms after started_at
artifact 2117 ms after started_at (35.8 MB)
solve 2854 ms after started_at
submit 3590 ms after started_at
result CORRECT flag 03b153da…bc48
Mastery
CORRECT on the first attempt, ranked (530 s clock). The eight archives were streamed; all were in by +4,688 ms.
started_at 2026-10-24T13:03:32.103Z
deadline 2026-10-24T13:12:22.103Z (530 s)
answers 2,304 (8 sets × 288)
start 374 ms after started_at
artifact 4688 ms after started_at (8 × ~35.7 MB, streamed; first in at +2108 ms)
solve 5219 ms after started_at
submit 6585 ms after started_at
result CORRECT flag dd57b601…f657
Around 09:18 ET the add-on went into the solver for the following days. Before that it was checked: re-solving 117 saved Binary sets gave 113 identical, the 3 Day 24 sets gaining answers only, and Day 1 a known gap; a replay of 47 saved Masteries was clean; the Day 24 accepted answers matched (288, 288, 2,304).
Time to solve
All three modes were solved by 09:03:38 ET, 3 min 38 s after release (2 min 29 s from the first start request). The Single Solve needed Claude to finish the last 6 answers; the Time Trial and Mastery were both ranked and went through on the first submit.
Takeaways
- A field restricted to one member inherits the shared answer. When the accepted config already required both builds to match, the corrected-only config could only be the same values. It was the first choice and it was right.
- Accepted-with-remaining is a clean stop. The solver sent 282 answers it could cover and left 6, so nothing was burned and both ranked runs were still first attempts.
- The prompt's theme didn't change the questions, again. "Diff the function" and "prove it was broken" sounded like bytecode work; the 12 fields were hashes, formats, and the usual config. Read the question list before planning around the prompt (as on Day 23).
- Write add-ons for
day >= Nand for streaming from the start. Today's add-on was both, so the streamed Mastery needed no second version. - Keep every reply that carries a flag. The Single Solve flag was lost to the log's cut; the timed runs, which save their submit replies, kept theirs.