# Variables

> Values the runtime fills in for you: built-ins, your own values, and values captured from the target.

Sometimes a step needs a value that is not known until the run happens: the port a server assigned, a token it issued, or the path to a flag file. Variables let a solution refer to those values by name and let the runtime fill them in.

## How a reference looks

A reference is a name in curly braces, like `{flag_path}`. Wherever the runtime sees one, it replaces it with the actual value before the step runs. The file says `{port}`; the target's answer provides the port; the next step uses it.

## Built-in variables

Three values come from the command line or the run itself:

| variable | what it holds |
| --- | --- |
| `{flag_path}` | the path from `--flag-path`, for steps that read a flag file |
| `{oob_host}` | the out-of-band listener host, when the solution has one |
| `{oob_port}` | the out-of-band listener port, when the solution has one |
| `{oob_body}` | the body of the most recent out-of-band callback, refreshed after every step (the command output of an HTTP exfil callback) |

## Your own values

A solution can declare its own values and reuse them. Two places do this:

- `vars` at the top of the file sets starting values, available to every step
- `set` on a step sets or changes a value for the steps that follow

```text
id: demo/probe
vars:
  marker: ONE

http first
  get with "{marker}"
  set:
    token: TWO
  expect "ONE" in the response

http second
  get with "{token}"
  expect "TWO" in the response
```

Step 1 sends `{marker}` (which is `ONE`) and declares `{token}` as `TWO`. Step 2 sends `{token}` (which is now `TWO`). A later `set` on the same name wins, so a value can change as the attack progresses.

A few rules keep this simple: the built-in names are reserved, so your own values cannot use `flag_path`, `oob_host`, `oob_port`, or `oob_body`. One `vars` or `set` block cannot repeat a name.

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 AES-GCM sealed bound argument (base64 of iv plus ciphertext) for later steps. This is how a solution forges Next.js Server Action bound arguments from a leaked encryption key.

## Values taken from the target

A `capture` pulls a value out of a step's response for the steps that follow. This is how a solution follows a value the server assigns, like a session port. The identity pages show the form and an example for each protocol.

A capture can also decode a value before it is stored. The shape form reads as English: `capture the attribute "ID" of saml_b64 base64 as reqid` says take the variable `saml_b64`, base64-decode it, find the `ID` attribute, and store its value as `reqid`. The program knows the shape; the author names the value. See [Steps](/docs/solution/steps/) for the full capture form.

## Which value wins

Before a step runs, the runtime collects the built-ins, the solution `vars`, and every `set` or `capture` written by earlier steps. A later write wins. A step's own `set` and `capture` apply to the steps after it, not to itself.

## Example

```text
file read-flag
  read "{flag_path}"
  expect a flag
```

The runtime fills `{flag_path}` from the `--flag-path` flag before running the step.