Skip to main content

String Matcher

String values in phishlets serve two purposes: as literal values or as search patterns. This reference documents the pattern matching syntax used in the Phishlets V2 format.

Where matchers appear

Matcher syntax is accepted by any field documented as [matcher] or [[]matcher]. The most common are hostname, path, header, method, mime_types (on a Trigger), and match_key / match_value (on a Locator).

Parameters & Placeholders​

Strings can include dynamic placeholders that are replaced at runtime with configured values.

Syntax​

Use ${parameter-name} to insert a parameter value:

hostname: "akira.${lab-domain}"

Naming Rules​

Parameter names can only contain:

  • Alphanumeric characters (a-z, A-Z, 0-9)
  • Hyphen (-)
  • Underscore (_)
  • Colon (:) — reserved for value modifiers

Escaping​

To use a literal $ character, escape it with a backslash:

value: "Price: \\$100"

Value Resolution​

Parameter values are resolved with the following priority (highest to lowest):

  1. Captured custom tokens — values captured during the proxy session
  2. Lure custom parameters — values defined in the lure URL
  3. Phishlet parameters — default values defined in the phishlet

When a parameter exists in multiple sources, the higher-priority source overwrites the lower.

Search & Replace​

A matcher is most commonly paired with a replacement value inside a rewrite block. The matcher locates the data; the value becomes the replacement:

{
locator: { scope: "headers", match_key: "Host", match_value: '*.google.com' },
rewrite: { action: "update", key: "@", value: 'replaced.domain.com' }
}
  • match_value — the search pattern (glob or regex)
  • value — the replacement string

Pattern Types​

PrefixTypeExample
(none)Glob pattern*.google.com
~Regular expression~([a-z]+)\.google\.com

To use a literal ~ at the start of a glob pattern, escape it:

match_value: '\\~tilde-file.txt'

Glob Patterns​

Glob patterns are the default when no prefix is specified. They use wildcards to match strings.

Common Wildcards​

PatternMatches
*Any sequence of characters (except path separators)
**Any sequence of characters (including path separators)
?Any single character
[abc]Any character in the set
[!abc]Any character not in the set

Reference​

For complete glob pattern syntax, see the VS Code glob pattern documentation.

Escaping​

Escape glob special characters with a backslash when you need literal matches:

match_value: 'file\\[1\\].txt'

Regular Expressions​

Prefix a pattern with ~ to use regular expression matching. Regex follows Go's RE2 syntax.

{
locator: { scope: "headers", match_key: "Host", match_value: '~([a-z]+)\\.google\\.com' },
rewrite: { action: "update", key: "@", value: '${1}.proxy.com' }
}
tip

Test your regular expressions at regex101.com (select the Golang flavor).

Case-Insensitive Matching​

Enable case-insensitive matching for the entire pattern:

match_value: '~(?i)google'

Or for a specific portion:

match_value: '~(?i:Google)\\.com'

Capture Groups​

Use capture groups to reference matched substrings in the replacement value:

PlaceholderContains
${0}The entire matched string
${1}First capture group
${2}Second capture group
${n}nth capture group

Example:

{
locator: { scope: "headers", match_key: "Host", match_value: '~([a-z]*)\\.(google\\.com)' },
rewrite: { action: "update", key: "@", value: '${1}.proxy.${2}' }
}

Input: mail.google.com → Output: mail.proxy.google.com

Value Modifiers​

Modifiers transform parameter values before substitution. Specify a modifier after the parameter name using a colon.

Syntax​

${parameter-name:modifier}

Available Modifiers​

ModifierDescription
regexpEscapes all regular expression special characters in the value

Example:

{
locator: { scope: "body", format: "raw", match_value: '~${user-input:regexp}' },
rewrite: { value: 'replaced' }
}

If user-input is user+test@example.com, the pattern becomes ~user\+test@example\.com.

Examples​

URL Query Parameter Modification​

Update a query parameter value:

{
trigger: { hostname: "example.com", path: "*" },
locator: { scope: "url_query", match_key: "param", match_value: '*' },
rewrite: { action: "update", key: "@", value: 'newvalue' }
}

Create a new query parameter:

{
trigger: { hostname: "example.com", path: "*" },
locator: { scope: "url_query" },
rewrite: { action: "create", key: "tracking", value: 'disabled' }
}

Header Modification​

Modify the User-Agent header with regex capture groups:

{
trigger: { hostname: "example.com", path: "*" },
locator: {
scope: "headers",
match_key: "User-Agent",
match_value: '~(.*)\\sChrome\\/([0-9\\.]*)(.*)'
},
rewrite: { action: "update", key: "@", value: '${1} Chrome/999.0.0${3}' }
}

Update a cookie using case-insensitive regex:

{
trigger: { hostname: "example.com", path: "*" },
locator: { scope: "cookies", match_key: "session", match_value: '~(?i)token' },
rewrite: { action: "update", key: "@", value: 'modified' }
}

Body Content Replacement​

Replace email patterns in a response body:

{
trigger: { hostname: "example.com", path: "*" },
locator: {
scope: "body",
format: "raw",
match_value: '~([a-zA-Z0-9.]+%40[a-zA-Z0-9.]+)'
},
rewrite: { value: 'redacted@example.com' }
}

Using Parameters in Hostnames​

Define reusable domain parameters:

{
params: [
{ name: "domain", value: "example.com", required: true }
],
proxy: {
hosts: [
{ hostname: "app.${domain}" },
{ hostname: "api.${domain}" }
]
}
}