AI LOAD INSTRUCTION: Yakit plugins are divided into "native plugins" (saved as YakScript, with an independent execution page/parameter form) and "hot patching" (inline code in the MITM/Fuzzer Tab). This page focuses on native plugins +
cliparameter system:cli.*calls are statically scanned by Yakit into a parameter form, and at runtime the values filled in by the user are injected back into the script. Three runnable examples are given: a yak native plugin collecting input via cli, a mitm native plugin passively scanning complex content, and a mitm + cli interactive plugin loading external parameters. All examplesyak <file>self-tested and passing.
0. Related routes
- Main entry: yak
- All MITM hooks and deduplication semantics (from the hot patching perspective, but the hook contract is the same as for native mitm plugins): mitm-hotpatch
- Right-click codec plugin + cli selection of extraction items: yakit-rightclick-plugin
- Historical data extraction/dictionary/packet sending: yakit-data-extract-plugin
- Database / Payload dictionary / risk: yaklang-database
- Validation toolchain: yaklang-toolchain
1. Native plugins vs hot patching (distinguish first)
| Dimension | Native plugin (this page) | Hot patching (hot patch) |
|---|---|---|
| Form | Saved as YakScript, with name/type/parameters | Inline code snippet in the MITM/Fuzzer Tab |
| Parameters | Defined with cli.* definitions, rendered by Yakit into a form |
No independent form, edit the code directly |
| Entry | Top-level statements execute directly (yak type); mitm type registers hooks | Register hook functions |
| Suitable for | "Finished tools" for team reuse | Temporarily modifying traffic/quick experiments |
| Topic in this repository | This page | mitm-hotpatch / webfuzzer-hotpatch / global-hotpatch |
Key: mitm native plugins and MITM hot patching use the same set of hooks(
hijackHTTPRequest/mirror*/hijackSaveHTTPFlow...), contract see mitm-hotpatch. The only difference is that native plugins can superimposecliparameter forms, and are saved/distributed as finished products.
2. cli parameters -> Yakit form controls (core comparison table)
cli.* are all written at the top level(executed at module load), so that Yakit can statically scan out the parameters. At runtime the engine injects the values filled in by the user.
| cli function | Return type | Yakit control | Description |
|---|---|---|---|
cli.String(name) |
string | Single-line text | Most commonly used |
cli.Text(name) |
string | Multi-line text box | Large blocks of text |
cli.Int(name) |
int | Number | |
cli.Float(name) |
float | Number | |
cli.Bool(name) |
bool | Switch | true if present |
cli.Urls(name) |
[]string | URL list | Automatically prepends http(s):// |
cli.Ports(name) |
[]int | Port | Supports 80,443,8000-8010 |
cli.Hosts(name) |
[]string | Network target | Supports CIDR expansion |
cli.StringSlice(name) |
[]string | Dropdown/multi-select | Configure setSelectOption for dropdown |
cli.File(name) |
[]byte | File | Read file content |
cli.FileOrContent(name) |
[]byte | File or text | If the file cannot be read, treat it as text |
cli.LineDict(name) |
[]string | File or multiple lines | by linesplit (not comma) |
cli.YakitPlugin() |
[]string | Plugin selection | Read yakit-plugin-file |
cli.Json(name) |
map | Complex forms | Configure setJsonSchema |
Option function (option, passed in as subsequent parameters):
| Option | Purpose |
|---|---|
cli.setRequired(true) |
Required; when missing cli.check() print help and exit |
cli.setDefault(v) |
Default value |
cli.setVerboseName("中文名") |
Chinese label displayed in the form |
cli.setHelp("...") |
Help description |
cli.setCliGroup("分组名") |
Parameter group |
cli.setSelectOption("显示名","值") |
Dropdown options (only cli.StringSlice) |
cli.setMultipleSelect(false) |
Whether multiple selection (only cli.StringSlice) |
At the end, must call
cli.check(): validate required items; if missing, print Usage andos.Exit(1)。
target = cli.String("target", cli.setVerboseName("目标"), cli.setRequired(true))
ports = cli.Ports("ports", cli.setDefault("80,443"))
mode = cli.StringSlice("mode",
cli.setSelectOption("快速", "fast"), cli.setSelectOption("深度", "deep"),
cli.setMultipleSelect(false), cli.setDefault("fast"))
cli.check()
3. Three excellent examples (examples/)
| Example | File | Key points |
|---|---|---|
| yak native plugin uses cli to receive input | examples/yak-cli-input.yak | cli.Urls/Ports/Int/Bool + cli.check(); extract core logic into pure functions for easy self-testing |
| mitm native plugin passively scans complex content | examples/mitm-passive-scan.yak | mirrorNewWebsitePathParams scan response body for phone numbers/ID cards/JWT/AKSK, on hit risk.NewRisk |
| mitm + cli interactively loads external parameters | examples/mitm-cli-interactive.yak | cli.LineDict read external keyword dictionary + cli.String limit scope, hook closure captures and drives scanning |
3.1 yak native plugin + cli (excellent example 1)
The entry point of a yak-type plugin is top-level statements(yak will not automatically call func main()). A real plugin's top level directly reads cli parameters and executes the main flow:
func runPlugin() {
targets = cli.Urls("target", cli.setRequired(true))
ports = cli.Ports("ports", cli.setDefault("80,443"))
cli.check()
// ... 用参数做扫描/发包
}
runPlugin() // 真实插件: 顶层直接调用
Extract the core logic (target normalization, deduplication) into pure functions, so that in the YAK_MAIN self-test block you can make repeatable assertions without the command line/network.
3.2 mitm native plugin passive scanning (excellent example 2)
mitm plugins do not write main, but instead register hooksFor passive scanning, prefer mirrorNewWebsitePathParams(deduplicate by path + parameter structure, save compute, read-only and does not affect forwarding):
mirrorNewWebsitePathParams = func(isHttps, url, req, rsp, body) {
for f in scanSensitive(string(body)) { // scanSensitive 是纯函数, 可自测
risk.NewRisk(url, risk.title(...), risk.type("info-leak"),
risk.severity("low"), risk.payload(f.value))
}
}
- Put the rule table at the top level as read-only constants(do not modify globals in concurrent hooks, it will cause a data race).
- On hit, produce
risk.NewRisk(...), visible in Yakit's "Risks and Vulnerabilities" panel. - For self-testing, only test
scanSensitivepure logic, do not callrisk(to avoid writing to the database).
3.3 mitm + cli interactive (excellent example 3)
For the same mitm plugin, use cli to make "keyword dictionary" and "scope" into parameters, so changing targets does not require changing code:
KEYWORDS = cli.LineDict("keywords", cli.setDefault("password\ntoken\nsecret")) // 顶层读取
SCOPE = cli.String("scope", cli.setDefault(""))
cli.check()
mirrorHTTPFlow = func(isHttps, url, req, rsp, body) { // 闭包捕获 KEYWORDS/SCOPE
if !inScope(url, SCOPE) { return }
for kw in matchKeywords(string(rsp), KEYWORDS) { risk.NewRisk(url, ...) }
}
Collaboration key point: cli at the top level loads once, and the hook closure repeatedly reuses these values at runtime.
cli.LineDictsplit by line , if you want CSV compatibility, flatten it yourself withstr.Split(line, ",")(see exampleflattenKeywords)。
4. Standard pattern: entry point + YAK_MAIN self-test
// yak 类型: 顶层执行; mitm 类型: 注册 hook + 顶层 cli
mirrorHTTPFlow = func(isHttps, url, req, rsp, body) { /* ... */ }
func runSelfTest() { /* 用纯函数 + mock 数据 + assert 验证 */ }
if YAK_MAIN {
runSelfTest()
}
YAK_MAIN is a global boolean injected by the engine:
yak xxx.yakRun from the command line:YAK_MAIN = true-> run self-test.- Yakit loading the plugin: top-level cli/hook registration executes as usual, and the self-test block is guarded as needed.
Note:
cli.Args()always includes the script file name (length >= 1). To distinguish "self-test / real run with parameters", uselen(cli.Args()) > 1to determine (seeyak-cli-input.yak)。
5. Verification
cd /Users/v1ll4n/Projects/yaklang
# 自测(走默认/纯逻辑)
yak skills/yakit-native-plugin/examples/yak-cli-input.yak
# 体验真实参数注入
yak skills/yakit-native-plugin/examples/yak-cli-input.yak --target "yaklang.com,example.com:8443" --ports 80,443 --probe
Acceptance criteria: complete within 10 seconds, all assert passed,log all in English, ending with ... self test passed.
mitm native plugins can be further used with yak hotpatch-mitm to feed real requests for verification (see yaklang-toolchain)。
Reference Sources
- cli argument system:
yaklang/common/utils/cli/cli.go(CliExports) - mitm hook contract:
yaklang/common/yak/hook_mixed_plugin_caller.go - risk API:
yaklang/common/yak/yaklib/risk.go(risk.NewRisk/risk.title/risk.severity...) - training material cross-reference:
yaklang-ai-training-materials/library-usage/cli、.../risk