The challenge
Exploit seeded nonces or weak derivation without bypassing earlier storage gates.
One question, answer: "For case MOB-14-… in package com.huntress.mobile.d14.…: Exploit seeded nonces or weak derivation without bypassing earlier storage gates. Submit only the exact backend answer code returned for this case." Format: ANS- + exactly 16 uppercase hex characters, normalization exact. Mastery asks the same question three times (set1.answer to set3.answer), one per APK.
Reading the prompt: what it said we'd need
| Clue | What it pointed to | What I did about it |
|---|---|---|
| "seeded nonces or weak derivation" | an app that builds its crypto from a fixed seed or a guessable key, so the output can be recomputed | Not needed for the answer. The DEX only carries the label predictable_; the answer sits in the packaged puzzle asset |
| "without bypassing earlier storage gates" | the storage and Keystore themes of Days 11 and 13, so don't skip steps by patching the app | Nothing was patched or run. The APK was read as a zip |
| "backend answer code returned for this case" | a runtime service | As on Day 10: the app points at a loopback URL nothing serves; the code is the decoded assets/ |
ANS- + 16 uppercase hex, exact |
a strict check | The solver checks the decoded value against this format before sending |
The full method is in the Network Config Split write-up.
Safety
Static only. Each APK was opened as a zip in Python (python3 -I) on our Kali VM. The puzzle asset was read, and printable strings were pulled from classes.dex and the binary manifest. Nothing was installed, run, or decompiled to code. The APKs stayed on the VM.
What was in the files
Five APKs (Single Solve, Time Trial, three Mastery deliveries), each 12,704 bytes, all built from one template: AndroidManifest.xml, classes.dex, assets/huntress_puzzle.json, and a FIXTURE- signature.
The codec today was caesar (as on Day 7): take each character's code and subtract key. For example, the Single Solve data starts JW\6L, and with key 9 that gives ANS-C. Every mode used caesar, with a new key each time:
| Mode | APK | sha256 (first 16) | Key | Answer |
|---|---|---|---|---|
| Single Solve | predictable_ |
b6d3fff1c44485ea |
9 | ANS- |
| Time Trial | predictable_ |
ef619068a4795a4a |
10 | ANS- |
| Mastery 1 | predictable_ |
a684fcd3da1214e1 |
17 | ANS- |
| Mastery 2 | predictable_ |
1ef24b5759bc5ade |
4 | ANS- |
| Mastery 3 | predictable_ |
0a50cf28cd77204f |
7 | ANS- |
The "predictable crypto" theme was a label, not real crypto. The manifest has meta-data huntress.mechanic = "predictable nonce and derivation". The DEX has a PredictableCrypto class and the strings predictable_rng, caesar, encode, and DAY-14:predictable_rng:predictable nonce and derivation. It also has a fixture client_secret=SECRET-…&proof= string, which differs per APK. No javax/crypto, java/security, or java/util/Random references showed up in the strings. So the only "weak derivation" in play is the one in the asset: a fixed shift with its key stored right beside the data. I can't say more from strings alone. What encode does with the secret was not traced, and it wasn't needed.
As on earlier days, ChallengeActivity (deep link huntress14://predictable-crypto/unlock) reads answer and case_id and loads http://127.0.0.1:19090/mobile/attempt/d14-…/evidence in a WebView. Nothing serves that port.
What the timed variants changed: only the values. Each had a new case ID, package suffix, caesar key, data, client secret, and loopback attempt ID. The template, the codec, and the file size stayed the same.
Single Solve
The solver started the untimed Single Solve, fetched the APK, and checked its hash. It found one caesar asset, decoded it to ANS-C539C482FC5EE146, confirmed it fits the format, and sent it once.
started_at 2026-10-14T13:00:20.803Z deadline none (untimed)
answer ANS-C539C482FC5EE146
timings start 527 artifact 388 solve 1 ready 0 submit 986 TOTAL 1902 ms
vs started_at: start +106, artifact +494, ready +494, submit +1480 ms
result CORRECT 1f423662…d5e3 (solved_by.at 13:00:21.672Z)
Time Trial
Started about 7 s after the Single Solve, as the solver's pacing allows. The start reply said unique_attempts_remaining: 0 and hall_of_fame_eligible: False, as on Day 13. So this run was unranked. The saved files don't say why; that is how the Game Master answered on the first start.
started_at 2026-10-14T13:00:27.804Z deadline 13:00:57.804Z (30 s clock)
answer ANS-FFDA049C74988184
timings start 567 artifact 457 solve 1 ready 0 submit 870 TOTAL 1895 ms
vs started_at: start +95, artifact +552, ready +552, submit +1423 ms
result CORRECT 2aaf74e8…3358 (solved_by.at 13:00:28.686Z)
Mastery
Three APKs, named delivery N: predictable_crypto_mastery_0N.apk in the questions. The delivery matcher fixed on Day 10 paired them correctly. All three answers went in one submit. Again unique_attempts_remaining: 0 and hall_of_fame_eligible: False. The start step took 1,161 ms, about twice the others; our request log shows the request at 13:00:34 and the reply at 13:00:35. The cause isn't in the saved files.
started_at 2026-10-14T13:00:35.353Z deadline 13:01:05.353Z (30 s clock)
answers set1 ANS-2C1197C6BA89DA27 set2 ANS-4561FFEA182C4655 set3 ANS-7DE42633A78D6CAA
timings start 1161 artifact 395 solve 1 ready 0 submit 915 TOTAL 2472 ms
vs started_at: start +83, artifact +478, ready +479, submit +1394 ms
result CORRECT 6df7e208…be27 (solved_by.at 13:00:36.084Z)
No failed attempts, no retries, and no HTTP 429s for this challenge.
Time to solve
All three modes were solved by 09:00:36 ET, 15.3 s from the first start to the last CORRECT, each on the first submit. Both timed runs were unranked.
Takeaways
- The puzzle-asset solver carried over again: a codec it already knew (
caesar, first seen Day 7), no change, all three modes unattended in about 15 s. - The theme was a label. "Seeded nonces" and "weak derivation" showed up only as names in the manifest and DEX. The real weak point was a fixed-key shift with the key stored next to the data.
- Timed runs are still unranked: both timed starts said
hall_of_fame_eligible: False, as on Day 13.