# Steps

> A step is one action. What a step is, every field on a step, and how the runtime runs it.

A solution is a list of steps, and each step is one action. Think of a step as one line in a checklist: do this, then look for that. The runtime works through the list in order and checks each response as it goes.

## A step, annotated

```text
http reflect
  get with "REFLECTED_7x7"
  # send a unique marker in the template param and confirm it comes back
  expect "REFLECTED_7x7" in the response
```

What this step does:

- `http` is the protocol and `reflect` is the step name
- `get with "REFLECTED_7x7"`: send the value `REFLECTED_7x7` in a GET parameter on the target
- `expect "REFLECTED_7x7" in the response`: pass only if the response contains the marker

The whole step is one idea: send a marker, confirm the target reflects it. This is the classic test for a reflection point. A `#` comment explains what a step does; the runtime skips comment lines, so they never affect the run.

## Steps in English

An http step is written as English sentences; the program does the heavy lifting. `get` fetches a page, `post` sends to one, and `expect` checks the response:

```text
http sso
  get "/login"
  expect "SAMLRequest" in the response
  capture the form field "SAMLRequest" as saml_b64

http deliver
  post /acs as a form field SAMLResponse with base64 of "<samlp:Response InResponseTo=\"{reqid}\"/>"
  expect "accepted" in the response
```

The `get` and `post` sentences set the method, path, and payload; the `expect` sentence is the assert. `get with <value>` gets the target itself with the value in a query parameter, the form a template-renderer target expects. See the [http identity](/docs/solution/identity/http/) for the full directive list.

## How a step runs

When the runtime reaches a step, four things happen in order:

1. It fills in any values the file references (see Variables).
2. It talks to the target: sends what the step says to send, then reads the response.
3. If the step has a test, it checks the response against it.
4. It hands any new values from the step to the steps that follow.

## One conversation or many

For `tcp`, `tls`, and `websocket` steps the connection stays open across steps. This matters for attacks that need a handshake first: stage the handshake in one step, send the exploit in the next, on the same connection. A `close the connection` sentence ends the session when a step is done.

For `http` steps each step is its own request. Nothing carries over from the previous HTTP step.

On the byte-session identities (`tcp`, `tls`, and the rest) a step reads as sentences: `send hex "<hex>"` (or `send hex of "<text>"`), `receive <n> bytes`, `receive until "<hex>"`, `port <n>`, `timeout <n> seconds`, `close the connection`, and `expect ...`. On `websocket`, `send` is plain text. On `process` and `file`, `run "<command>"`, `read "<path>"`, and `write "<path>" with "<data>"` are the directives.

## Pass, fail, and the result

A step without a test never fails. When every step with a test passes, the run is verified. When any step fails, the run is not verified.

## The step fields

Every step has two required fields, the `identity` and the step name. The directives that follow depend on the protocol in `identity`; the full detail for each protocol is on its identity page. A step can also carry `set`, `capture`, and `expect` whatever the protocol.

### identity field

Required on every step. The protocol this step speaks, and it decides which other fields apply. The runtime implements eighteen protocols today: `http`, `https`, `websocket`, `tls`, `tcp`, `ssh`, `ftp`, `smtp`, `dns`, `snmp`, `ldap`, `redis`, `mysql`, `postgresql`, `smb`, `telnet`, `process`, and `file`; the vocabulary is open and grows with the runtime. Each protocol has its own page with the full field detail (see Fields per identity below).

### set field

Optional. Values to hand to later steps, in the same form as the solution-level `vars`. A later `set` on the same name wins. Reserved names are rejected. See [Variables](/docs/solution/variables/).

A `set` line can also compute a value: `set <var> = aesgcm of "<plaintext>" with "<base64-key>"` runs after the step's captures and stores the sealed bound argument (`base64(iv + ciphertext)`, 16-byte iv) for later steps. This is the primitive used to forge Next.js Server Action bound arguments from a leaked encryption key.

### capture field

Optional on `http`, `tcp`, `tls`, and `websocket` steps. Pulls a value out of the response for later steps: on `http` steps from the full response text (status line, headers, and body), on `tcp`/`tls`/`websocket` steps from the received hex. See the capture form below.

### expect directive

Optional on any step. The pass or fail test on the response. A step without an expect never fails. See the assert form below and [Asserts](/docs/solution/asserts/).

## The assert form

```text
expect ... 
```

The pass or fail test on the response. There are five forms:

- `expect "<text>" in the response`: the response contains the exact text
- `expect the response to match "<regex>"`: the response matches the pattern
- `expect a flag`: the response contains a flag-shaped string such as `FLAG{...}`
- `expect the target to call back "<expect>"`: the target contacted the out-of-band listener; when the callback is an HTTP POST carrying exfiltrated data, the report line shows the callback body
- `expect no response`: the target never answered

The `contains`, `regex`, and `oob` forms take a value. The `flag` and `empty` forms take none.

### note field

Optional. A plain-language explanation of what passing means, printed with the step result.

## The capture form

A capture pulls a value out of the response for later steps, and it reads as English. The program does the heavy lifting: it knows page shapes, so you name the thing and it finds the bytes.

The shape form names a thing the page holds:

```text
capture the <shape> "<name>" [of <source>] [base64] as <var>
```

Shapes are `form field` (an HTML input's `value`), `attribute` (an XML or HTML attribute), `json field` (a JSON string field, raw or HTML-escaped), `query parameter` (a URL query value, raw or HTML-escaped), `cookie` (a `Set-Cookie` value), `value after` (on a byte-family step, the hex after a hex marker), and `input name after` (the tail of an HTML input's name after a prefix). `<var>` is the name later steps use as `{var}`. `of <source>` (optional) searches an earlier variable instead of this step's response. `base64` (optional) decodes the source first.

```text
capture the attribute "ID" of saml_b64 base64 as reqid
```

Reads: capture the `ID` attribute, from `saml_b64`, base64-decoded, as `reqid`. No markup, no pattern.

The template form matches literal text with one `<name>` placeholder where the value appears:

```text
capture <var> [from <source>] [base64] where "<text with one <name> placeholder>"
```

The regex form is the same with a pattern instead of a template:

```text
capture <var>: <regex> [from <var>] [base64]
```

The first capture group is the value that is stored. The source (`from` or `of`) must name a variable declared before the step: a solution `var`, a built-in, an earlier step's `set` or `capture`, or an earlier capture on the same step.

## Fields per identity

Which fields apply depends on the `identity`:

| identity | directives |
| --- | --- |
| `http` | a method line (required), `with the header`, `with the cookie`, `capture`, `expect` |
| `websocket` | `send` (required), `receive`, `receive until`, `timeout`, `close the connection`, `capture`, `expect` |
| `tls` | `send` (required), `receive`, `receive until`, `timeout`, `close the connection`, `capture`, `expect` |
| `tcp` | `send` (required), `receive`, `receive until`, `timeout`, `close the connection`, `capture`, `expect` |
| `process` | `run` (required), `expect` |
| `file` | `read` or `write` (required), `expect` |

Each identity has its own page with the full detail: [http](/docs/solution/identity/http/), [websocket](/docs/solution/identity/websocket/), [tls](/docs/solution/identity/tls/), [tcp](/docs/solution/identity/tcp/), [process](/docs/solution/identity/process/), and [file](/docs/solution/identity/file/).

## Determinism

Keep steps deterministic: fixed bytes, fixed paths, no randomness. The same solution against the same target should give the same result, so a run can be repeated and compared any time.

See [Variables](/docs/solution/variables/) for how values flow between steps and [Asserts](/docs/solution/asserts/) for the pass or fail tests.