zwesty
Write-ups / Day 12 / Android
Day 12 · Mon, Oct 12 · Android

SQLite Assumptions

Prey slaughtered

Static APK inspection, reading a packaged puzzle asset, matching Mastery deliveries to their questions

STTMClaude Homebase Both

Flags are shortened to their first 8 and last 4 characters because they're unique per team.

Challenge ID
mobile-android-day-12-sqlite-assumptions (+ /time_trial, /mastery)
Solved
2026-10-12, all three modes CORRECT on the first submit, by 09:08:16 ET; 7 min 58 s from first start to last CORRECT. The gap is HTTP 429, not the solve: the 08:58 scheduled run did the Single Solve and was then rate-limited; the timed modes went in from a manual rerun at 09:08. Both timed runs were unranked
Player
Zwesty (solo), with Claude Code (Opus 5.5): solved by our automated morning solver (a scheduled script on our Kali VM) at 08:58 and its 09:08 manual rerun, with our shared Android solver

The challenge

"Reconstruct authorization from a synthetic SQLite cache and prove server-side impact."

answer_id Question Format
answer "For case MOB-12-… in package com.huntress.mobile.d12.…: Reconstruct authorization from a synthetic SQLite cache and prove server-side impact. Submit only the exact backend answer code returned for this case." pattern: ANS- followed by exactly 16 uppercase hex characters; normalization exact

Mastery asks the same question three times (set1.answer to set3.answer), one per APK, each named delivery N: sqlite_assumptions_mastery_0N.apk.

Reading the prompt: what it said we'd need

Clue What it pointed to What I did about it
"synthetic SQLite cache" an app that keeps its authorization state in a local database Nothing new. As on every Android day since Day 10, the answer sits in the packaged puzzle asset, not in app logic
"Reconstruct authorization" the theme of Day 11 (Local Secrets): trust in local storage No change to the solver; the morning solver used it as it was
"prove server-side impact", "backend answer code returned for this case" a runtime service The app points at a loopback URL nothing serves; the code is the decoded asset (method in the Network Config Split write-up)
ANS- + 16 uppercase hex, exact a strict check The solver checks the decoded value against this format before sending

Safety

Static only. The solver opened each APK as a zip in Python on our Kali VM and read the puzzle asset. Nothing was installed, run, or decompiled. This write-up was built from the solver's reports, the saved Game Master replies, and the request log only. The APKs weren't reopened for it.

What was in the files

Five APKs, each 12,704 bytes, one template (the same size as every Android day since Day 10):

Mode APK sha256 (first 16) Answer
Single Solve sqlite_assumptions.apk dc892f6eb2696690 ANS-039F0D9071111050
Time Trial sqlite_assumptions_time_trial.apk 7e9d44988c0e3da4 ANS-668B39E20D9A458F
Mastery 1–3 sqlite_assumptions_mastery_01.apk … _03.apk (set 3: 0e96089ef67c4f2f) ANS-CF8DBD28FC3C61A7, ANS-43D00DCBA9762EF1, ANS-A08AC2B1A2B70E61

Unconfirmed: which codec the asset used today. The solver's report doesn't print it, and the APKs weren't reopened for this write-up. The timed variants differed only in values (case ID, package suffix, answer); the size stayed the same.

Single Solve

The 08:58 scheduled run started the untimed Single Solve, fetched the APK, checked its hash, ran our shared Android solver, and sent one answer.

started_at  2026-10-12T13:00:18.268Z   deadline none (untimed)
answer      ANS-039F0D9071111050
timings     start 379  artifact 323  solve 1  ready 0  submit 1369  TOTAL 2072 ms
vs started_at (client clock): start +82, artifact +405, ready +406, submit +1775 ms
result      CORRECT  a585082d…64b3   (solved_by.at 13:00:18.919Z)

Then HTTP 429. The solver's next call, a status check, came back 429 rate_limited at 09:00:20 ET, and the run stopped before Android's timed modes, Binary, and Script. It had made only ~13 requests in ~20 s. John Hammond later explained that the allowance is per team, so the scheduled solver and our manual work share it.

Time Trial

From a manual rerun of the morning solver at 09:08 ET (Android, Binary, and Script only, 10 s between challenges). No 429 this time. The start reply said unique_attempts_remaining: 0 and unranked: a single-attempt, unranked route, like every Day 12 timed start.

started_at  2026-10-12T13:08:03.827Z   deadline 13:08:33.827Z (30 s clock)
answer      ANS-668B39E20D9A458F
timings     start 597  artifact 343  solve 0  ready 0  submit 1037  TOTAL 1977 ms
vs started_at (client clock): start +81, artifact +424, ready +425, submit +1462 ms
result      CORRECT  24229524…2751   (solved_by.at 13:08:04.755Z)

Mastery

Three APKs, saved as 01-…apk to 03-…apk; the matcher fixed on Day 10 paired each with its question. All three answers went in one submit. Again unique_attempts_remaining: 0, unranked.

started_at  2026-10-12T13:08:15.711Z   deadline 13:08:45.711Z (30 s clock)
answers     set1 ANS-CF8DBD28FC3C61A7  set2 ANS-43D00DCBA9762EF1  set3 ANS-A08AC2B1A2B70E61
timings     start 442  artifact 594  solve 1  ready 0  submit 727  TOTAL 1763 ms
vs started_at (client clock): start +74, artifact +668, ready +668, submit +1395 ms
result      CORRECT  e5c7f94c…0413   (solved_by.at 13:08:16.685Z)

No ranked time for this challenge. On 2026-10-15 Days 13–14 began to accept ranked-clock requests with fresh pools, but Day 12's routes still didn't, and a read-only sweep on 2026-10-12 (~16:40 ET) found no ranked Day 12 time anywhere.

Time to solve

The scheduled solver started the Single Solve at 13:00:18 UTC and had it CORRECT 0.7 s later, then stopped on an HTTP 429. The 09:08 manual rerun sent the unranked Time Trial (CORRECT in 0.9 s) and Mastery (CORRECT in 1.0 s at 13:08:16), each on the first submit: 7 min 58 s from the first start to the last CORRECT, about 7.5 min of it waiting out the 429.

Takeaways

  • The shared Android solver carried over again: no change, three CORRECTs, about 1 s of work each.
  • The rate limit cost more than the solve. The solver's own pacing (5 s between runs) wasn't enough at release. That evening the solver learned to wait out a 429 for 8 min and resume from status instead of stopping.
  • Every Day 12 timed route was single-attempt and unranked (unique_attempts_remaining: 0), a pool defect on Huntress's side (John Hammond's breakage list, item 2). The answers were right, but there's no speed time to show.