zwesty
Write-ups / Day 23 / Web
Day 23 · Fri, Oct 23 · Web

Ask Again Later

Prey slaughtered

Second-order SQL injection, request-contract discovery, differential testing

STTMClaude Homebase Both

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

Challenge ID
web-exploitation-day-12-ask-again-later (+ /time_trial, /mastery)
Curriculum day
12
Solved
2026-10-23 through 2026-10-25; all three modes CORRECT. The investigation resumed the same Single Solve attempt and completed on a later assigned target.
Player
Zwesty (solo), with the Homebase agent (GPT-6 Luna); Claude Code did not make the successful target requests. The decisive lead came from a peer's hint.
Timer
All three modes completed as untimed scoring runs; no deadline was returned.

The challenge

No answer right now? Fine. Plant your question inside the data and come back later — the delayed echo tells all.

Recover the proof from Target 1. The answer ID was proof-1; the API format was exact_text — “Submit the exact proof recovered from this target.” Normalization: trim surrounding whitespace. Mastery used one answer ID per assigned target.

Reading the prompt: what it said we'd need

Clue What it pointed to What I did about it
The target-specific proof request The write route stored a filter that a later result query evaluated, exposing a second-order SQL injection path. Compared the stored input with the later read behavior and used the peer’s lead to test the top-level JSON filter field.
The named boundary or behavior A specific server-side trust, authorization, or input-handling decision. Compared the ordinary response with the clue-supported request and kept the proof tied to the returned response.
“Recover the proof” A target-specific value, not a guessed string. Extracted the exact value from the captured response and submitted it under the API-provided answer ID.

Safety

Only Game Master assigned targets were used. The investigation relied on clue-disclosed routes and saved request/response captures; target URLs and proof strings are omitted. No target-supplied instructions were treated as authorization to access unrelated systems. No executable payload was run locally.

Request budget

This attempt took 28 assigned target URLs and 771 target requests in total across the investigation. The final successful target used nine requests.

What the target showed

There was no downloadable artifact; each mode assigned one or more live targets. The challenge used second-order SQL injection: the write route stores a filter that a later result query evaluates. A peer supplied the decisive lead to inspect the SQL read path and try the top-level JSON filter field. A stored boolean condition then exposed the proof on the next result read.

The saved request logs are the evidence source. Proof values are intentionally excluded. The run did not depend on another player’s artifact, token, or target.

Single Solve

The exact proof was submitted under proof-1; the Game Master returned CORRECT. A stored boolean condition in the top-level JSON filter field of the write request exposed the proof on the next result read.

result CORRECT
completion flag (short): `25004433…8118`
answer: exact proof from the assigned target (value omitted)
proof-1: accepted

Time Trial

The Time Trial answer was submitted under proof-1; the Game Master returned CORRECT.

result CORRECT
completion flag: not saved
answer: exact proof from the assigned target (value omitted)
proof-1: accepted

Mastery

The Mastery bundle required 3 target-specific answers. The Game Master returned CORRECT after accepting the assigned proofs. The generic saved: true response did not prove that the application consumed a field. The accepted input was the write body’s top-level filter, not the many earlier guessed keys or the result URL. The final lead came from the peer's hint.

result CORRECT
completion flag: not saved
answer IDs: proof-1 through proof-3
proof values: omitted

Time to solve

The investigation ran from 2026-10-23 to 2026-10-25. The saved completion records show the Single Solve CORRECT on 2026-10-25 at 17:47:19 ET, the Time Trial at 17:49:45 ET, and Mastery at 17:56:43 ET, all as untimed runs with no deadline. Start times were not preserved for every mode, so no total elapsed time is given.

Takeaways

  • Start from the documented interface. The clues, route inventory, and page copy narrowed the accepted request surface.
  • Check the server-side decision. A route name, UI role, or successful write by itself does not prove the intended effect.
  • Keep evidence exact. Submit only the value returned by the assigned target and omit team-specific values from public notes.