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:
varsat the top of the file sets starting values, available to every stepseton a step sets or changes a value for the steps that follow
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 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
file read-flag
read "{flag_path}"
expect a flag
The runtime fills {flag_path} from the --flag-path flag before running the step.