Lab 02 — Stateful Protocol Fuzzer Model

Difficulty: 4/5 | Runs locally: yes

Pairs with the Phase 08 WARMUP Chapters 3–4 (the fuzzing families, harness quality) and the HITCHHIKERS-GUIDE ("Stateful and Concurrent Targets").

Why This Lab Exists (Purpose & Goal)

Most fuzzing tutorials throw random bytes at a single function. But the most interesting bugs in real software live in state — a server that mishandles messages in the wrong order, accepts a second authentication, or processes data after a connection is closed. A single-buffer fuzzer never reaches those bugs because it can't get the protocol into a deep state. The goal of this lab is to build a stateful fuzzer that mutates message sequences against a protocol state machine, so it can explore the states where the real vulnerabilities hide.

The Concept, In the Weeds

The toy protocol is HELLO → AUTH → DATA* → CLOSE, and the fuzzer must detect the state-machine violations:

  • illegal transitionsDATA before AUTH, AUTH before HELLO (authentication bypass / state confusion);
  • duplicate auth — re-authenticating mid-session (privilege/identity confusion);
  • oversized data — resource abuse;
  • messages after close — use-after-close, a stateful analog of use-after-free.

The key engineering ideas that make a stateful fuzzer work:

  • Fuzz at the message-sequence level, not the byte level — you generate and mutate sequences so the fuzzer can reach DATA and CLOSE states, not just rattle HELLO.
  • Determinism is non-negotiable. Use deterministic mutation so a failure reproduces. A stateful target has more sources of nondeterminism (time, ordering, threads); without control you get flaky crashes you can't minimize or fix (Phase 08 WARMUP, Chapter 4).
  • Bound and reset sequence length and state between iterations, so the search is efficient and reproducible.

Why This Matters for Protecting the Company

Every networked service the company runs implements a protocol with state — authentication handshakes, session lifecycles, transaction sequences — and state-machine bugs are among the most damaging (authentication bypass, request smuggling, replay). They are invisible to naive fuzzing and easy to miss in code review because the buggy interaction spans multiple messages. When you can build a stateful fuzzer (or a stateful test suite) that systematically explores illegal sequences, you find the class of bug that single-message testing structurally cannot — and you protect the protocol implementations that the company's services depend on.

Build It

Generate valid and invalid message sequences for the protocol; detect illegal transitions, oversized data, duplicate auth, and post-close messages. Use deterministic mutation so failures reproduce.

LAB_MODULE=solution pytest -q
# Port the state machine to a libFuzzer/AFL++ harness for coverage-guided stateful fuzzing.

Validation — What You Should Be Able to Do Now

  • Design a stateful fuzz harness that mutates sequences and reaches deep protocol states.
  • Make a stateful target deterministic (control time/ordering/threads, reset state) so crashes reproduce and minimize.
  • Name the stateful bug classes (illegal transition, duplicate auth, post-close use) and the real-world vulnerabilities they map to.

The Broader Perspective

This lab teaches you to think about software as a state machine with invariants between states, not just a function over inputs — a lens that finds bugs others miss and that connects directly to the parser-differential work (Phase 01/02) and the microVM lifecycle state machine (Phase 06). Many of the worst real vulnerabilities are temporal: the bug isn't in any single message but in the sequence and the state transitions. Carrying the "what illegal sequence violates an invariant here?" question into every protocol, session, and workflow you review is what makes you find authentication bypasses and smuggling bugs that single-input testing — and most reviewers — walk right past.

Interview Angle

  • "Design a harness for a stateful protocol parser." — Fuzz message sequences against the state machine, in-process, structure-aware so it reaches deep states; seed valid exchanges; dictionary of tokens; deterministic (control time/randomness/threads, reset globals); bounded timeouts; sanitizers; plus a differential second implementation to catch state divergence without a crash.

Extension (Stretch)

Port the state machine to a real libFuzzer/AFL++ harness with sanitizers, and add a differential second implementation to surface state-divergence bugs that don't crash.

References

  • Phase 08 WARMUP Chapters 3–4; The Fuzzing Book (stateful/grammar-aware fuzzing).
  • AFL++ / libFuzzer documentation; HTTP request smuggling (a stateful protocol-level bug class).