zwesty
Write-ups / Day 28 / Android
Day 28 · Wed, Oct 28 · Android

Protocol Reconstruction

Prey slaughtered
STTMClaude Homebase Both

Flags are shortened to their first 8 and last 4 characters because they're unique per team. "Reconstruct the app-to-backend protocol and preserve nonce and ordering semantics."

What our automated solver did

Our automated morning solver (a scheduled script on our Kali VM) started the Single Solve at 09:00:42 ET, read the APK's puzzle asset, and found a codec it had never seen, packet. Its fallback (bounded one- and two-layer transforms) found no ANS- reading, so it stopped without sending anything.

The APK, read statically

Nothing was installed or run. The APK unzips to the usual layout: classes.dex, a binary AndroidManifest.xml, a fixture signature, and assets/huntress_puzzle.json:

{"schema":"huntress.mobile.puzzle.v1","day":28,"codec":"packet","data":"4841 14 414e532d…4143 11"}

(The data string is shown spaced and shortened.) Read as bytes, it is one frame:

Bytes Meaning
48 41 magic, ASCII HA
14 payload length, 20
20 bytes payload: ANS-601D…85AC
11 checksum: XOR of every earlier byte of the frame

The checksum holds, and the payload is exactly the answer format. The DEX names the control binary_protocol ("binary protocol framing") under class ProtocolReconstruction; the activity takes an answer and case id from an intent or deep link and loads a loopback evidence URL. None of that code was needed for the v1 asset.

Single Solve: CORRECT 09:03:55 ET (flag c44427d7…3780).

The solver

The Day 28 solver wraps the Day 26 one and adds packet: hex data is split into back-to-back HA|len|payload|xor frames that must use up every byte, with magic and checksum checked on each. Only a single frame is accepted. More than one frame means sequence or nonce rules nobody has seen yet, so the solver stops cleanly rather than guess an order. Twelve unit tests cover the real Single, synthetic frames (including a low checksum byte and a Mastery delivery N: name), and every stop case. A regression check against every answer the Game Master had already accepted (all 411 Android answers) found 0 mismatches.

Timed modes

Both timed modes came as v2 puzzles, where the answer is computed by DEX code rather than stored in the asset. The existing Day 25 static interpreter evaluated them unchanged.

  • Time Trial (ranked): CORRECT 09:06:31 ET, submitted 1.5 s after the start.
  • Mastery (ranked, 12 deliveries mixing Days 1–28 controls): CORRECT 09:06:38 ET, submitted 1.9 s after the start.

The Day 28 solver then became our Android solver for later days, after a regression rehearsal over 167 saved attempts showed 0 changed answers.

Takeaways

  • A new v1 codec still stops the automated solver. Here it was a two-minute read once a person looked at the bytes.
  • The prompt's "nonce and ordering" never showed up in any delivery. Multi-frame packets are the obvious next pre-build.