My goal for the weekend was deliberately small: finish one challenge without following a write-up, keep useful notes, and avoid turning the scoreboard into a measure of whether I belonged there. Two of those three things went to plan.

The event opened on Friday evening. By Saturday morning I had a terminal full of abandoned commands, twelve browser tabs, and exactly zero flags. That turned out to be the useful part. A CTF compresses the normal learning loop until every weak habit becomes visible: guessing instead of observing, changing several things at once, and failing to record what has already been ruled out.

01 / Web — trust boundaries

The first challenge looked like a tiny account portal. I spent far too long testing inputs before asking the simpler question: what does the application trust? The browser was sending an object identifier to an API endpoint, and the server returned a different record when that identifier changed. The interface hid the control; the request did not.

FIELD NOTE 01
$ curl -s /api/profile/7
{ "user": "guest", "access": "standard" }

$ curl -s /api/profile/8
{ "user": "operator", "access": "restricted" }

02 / Forensics — build the timeline

The second challenge came as a directory of logs. My first instinct was to search for suspicious words. That produced plenty of noise and no explanation. The breakthrough was sorting the events into a timeline and treating gaps as evidence rather than inconvenience.

  • Normal sign-in from a known address.
  • A burst of failed requests against an old endpoint.
  • A successful request with a new user agent.
  • An archive created seconds before outbound traffic spiked.

None of those events was decisive alone. Together they described a sequence. Once I could tell the story in plain English, finding the evidence for the flag became mechanical.

03 / Crypto — read the implementation

The crypto challenge was the one I expected to skip. The maths looked intimidating, but the bug was not in the algorithm; it was in how the program used it. A value that should have been unique was repeated, creating a relationship between messages that the scheme assumed would never exist.

I did not solve this one before the event ended. I did get close enough to understand the official solution afterwards, which felt more valuable than copying a working script. The difference between “I have no idea” and “I know which assumption failed” is a real piece of progress.

What I got wrong

  • I reached for tools before I had written down a hypothesis.
  • I treated every dead end as lost time instead of recording it as eliminated territory.
  • I stayed stuck alone for too long because asking for a hint felt like failing.
  • I optimized for flags when the actual objective was learning a repeatable process.

Next transmission

For the next event I am taking a smaller toolkit and a better template for notes. I want every challenge page to start with the same four questions: what do I know, what is controlled by the user, what crosses a trust boundary, and what result would disprove my current theory?

I placed nowhere. I also left with three techniques I can reuse and a much clearer picture of how I behave when I am stuck. For a first weekend, that is a result I will take.