yakit-rightclick-plugin
Yakit 右键插件 (codec 插件) 的使用与编程技巧。讲清 codec 插件只需要一个 handle(input) 函数, 配合插件类型 codec + 开关"用于数据包右键" (tag: allow-custom-context-menu-execute) 即可出现在 任意 HTTP 编辑器的右键菜单里; 还讲 History 右键(单选/多选)时 input=flow id 的特殊契约(可由 id 反查数据包提取 host 全部 path/参数名, 带 yakit.SetProgress 进度条与 db Yield 通道), codec 插件 叠加 cli 参数做下拉选择(提取 Path/参数名/Cookie), Web Fuzzer 选区做"奇怪变换", 以及如何用 yak codec-plugin 命令验证。当用户问"怎么写右键插件 / codec 插件怎么用 / History 右键提取数据 / Web Fuzzer 右键变换 / codec 带参数"时使用。右键插件是编写小工具最快的方式。
How do I install this agent skill?
npx skills add https://github.com/yaklang/yak-skills --skill yakit-rightclick-pluginIs this agent skill safe to install?
- Gen Agent Trust Hubpass
The skill provides legitimate templates and educational content for developing Yakit codec plugins. It demonstrates standard practices for data transformation and history analysis using the platform's internal APIs. No malicious behavior or security risks were detected.
- Socketpass
No alerts
- Snykpass
Risk: LOW · No issues
What does this agent skill do?
SKILL: Yakit 右键插件 (codec) 使用与编程
AI LOAD INSTRUCTION: codec 插件是 Yakit 里写"小工具"成本最低的方式——只需要一个
handle(input)函数。把插件类型设为codec并打开"用于数据包右键"开关, 它就会出现在 MITM/History/Web Fuzzer 等所有 HTTP 编辑器的右键菜单里, 把当前选中文本作为input传进来, 展示handle的返回值。本页讲 启用方式、编程契约、Web Fuzzer 右键的两层菜单, 以及命令行验证闭环。
0. 相关路由
- 总入口: yak
- 原生插件(yak/mitm) + cli 参数体系: yakit-native-plugin
- 验证工具链: yaklang-toolchain(
yak codec-plugin命令) - 历史数据提取/字典/发包: yakit-data-extract-plugin
- 数据库 / Payload 字典: yaklang-database
- 三类热加载: mitm-hotpatch / webfuzzer-hotpatch / global-hotpatch
1. codec 插件的唯一契约: handle(input)
// 一个最小可用的 codec 插件: 把选中文本 Base64 编码
handle = func(input /* string: 当前选中的文本 */) {
return codec.EncodeBase64(input) // 返回值即右键执行后的结果
}
- 入口函数固定叫
handle, 入参是选中文本 (string), 返回字符串。 - 没有选区时, 传入的是整个编辑器内容。
handle内可以用任意 yaklang 库 (codec/str/json/re/poc...)。- 后端执行就是
handle(input)这一句 (SafeCallYakFunction(ctx, "handle", [input])), CLI 与 Yakit UI 走的是完全相同的执行路径。
2. 怎么让它出现在右键菜单 (关键: 一个 tag)
在 Yakit 插件编辑器里:
- 插件类型选 codec。
- 打开开关 "用于数据包右键"。
这个开关本质是给 YakScript.Tags 加一个 tag:
| 开关文案 | tag 值 | 效果 |
|---|---|---|
| 用于数据包右键 | allow-custom-context-menu-execute | 出现在右键 → 插件扩展 子菜单 (codec 插件) |
| HTTP 数据包变形 | allow-custom-http-packet-mutate | 出现在右键 → HTTP数据包变形 (对整包变形) |
| 单条历史记录处理 | allow-custom-single-history-mutate | 在 History 单条记录右键可用 |
| 多条历史记录处理 | allow-custom-multiple-history-mutate | 在 History 多选记录右键可用 |
编辑器右键时, Yakit 用
QueryYakScript({Type:'codec', Tag:['allow-custom-context-menu-execute']})把所有带该 tag 的 codec 插件拉出来, 注入到 插件扩展 / AI工具 菜单。保存插件后会触发onRefPluginCodecMenu重新加载菜单。
3. 点击后发生了什么 (执行链)
选中文本 → 右键 → 插件扩展 → 你的插件
→ onOpenFuzzerModal { text(选中文本), scriptName }
→ DebugPlugin { Input: text, PluginName, PluginType: 'codec' }
→ 引擎执行脚本并调用 handle(input)
→ 结果流式回显在 "Codec结果" 面板
重要行为差异:
- codec 右键插件的结果展示在面板里 (Codec结果), 不会自动写回编辑器——需要手动复制。
- 内置"编码/解码" (右键 → 编码/解码, 无需插件) 以及 HTTP数据包变形插件
(
allow-custom-http-packet-mutate) 才会直接替换编辑器内容/整包。 - 想要"选中即替换", 在 Web Fuzzer 里用选区浮动菜单的编解码最顺手 (见第 5 节)。
4. 编程技巧 (写出好用的右键插件)
- 保持纯函数:
handle只依赖input, 不读外部状态, 结果可预测、好验证。 - 容错不抛错: 解码失败时返回友好提示字符串, 而不是 panic, 右键体验更好。
handle = func(input) { raw, err = codec.DecodeBase64Url(input) if err != nil { return "decode failed: " + input } return string(raw) } - 善用 codec 库:
EncodeBase64/DecodeBase64/EncodeBase64Url/DecodeBase64Url、UnicodeDecode、 各种 hash/对称加密都在codec里, 多数小工具一行搞定。 - 可逆优先: 编/解码类尽量保证
handle(handle(x))或编解码成对, 方便来回切。 - 先自测再上架: 写
if YAK_MAIN { runSelfTest() }, 用yak file.yak跑断言; 注意handle不要被YAK_MAIN包住 (它要常驻注册), 只把自测放进守卫块。
5. Web Fuzzer 编辑器的右键 (两层菜单)
Web Fuzzer 请求编辑器有两套交互, 都能调用编解码/插件:
A. Monaco 原生右键菜单
右键弹出, 分组包含:
- 编码 / 解码: 内置编解码 (base64/url/hex/...), 选中后可"替换内容"写回编辑器。
- HTTP数据包变形: 调用带
allow-custom-http-packet-mutate的插件, 对整包变形。 - 插件扩展 / AI工具: 调用带
allow-custom-context-menu-execute的 codec 插件 (结果进面板)。 - 插入标签/字典: 插入空字节、临时/Fuzz 字典、
{{yak:dyn(...)}}热加载标签、文件标签等。
B. 选区浮动操作条 (最常用)
选中一段文本时, 旁边浮出操作条:
- 编码: 把选中文字包成 fuzztag 并替换选区, 例如选中
admin→{{base64enc(admin)}}, 发包时由 Fuzzer 引擎渲染。 - 解码 / 智能解码: 走
AutoDecode自动识别编码并解出明文, 点"替换"写回。 - 插件 / AI: 同样把选区文本喂给 codec 插件 (结果进面板)。
经验法则: 想"选中即替换成 fuzztag"用浮动条编码; 想"看一眼解码结果"用浮动条解码/智能解码; 想"跑自己写的复杂转换"用右键插件扩展 → codec 插件。
6. 命令行验证 (与 UI 同款 handle 执行)
# 用 yaklang 源码引擎构建一次
cd /Users/v1ll4n/Projects/yaklang && go build -o /tmp/yak ./common/yak/cmd/yak.go
# 验证 codec 插件: 把 input 喂给 handle, 打印返回值
/tmp/yak codec-plugin --script skills/yakit-rightclick-plugin/examples/codec-base64-wrap.yak --input "admin:123456"
# -> output: YWRtaW46MTIzNDU2
# 也支持从文件读取 input
/tmp/yak codec-plugin --script x.yak --input-file /tmp/payload.bin
yak codec-plugin 与 Yakit 右键执行同样调用 handle(input), 所以"命令跑通 == 右键也能跑通"。
7. History 右键: input 是 flow id, 不是文本(重要契约)
普通 HTTP 编辑器右键时 input 是选中文本; 但在 History 表格行右键 跑 codec 插件时,
Yakit 传进来的 input 是这条记录的 flow id(已核实, 见 yakit 源码
components/HTTPFlowTable/useHTTPFlowTableContextMenu.tsx):
| 场景 | tag(开关) | 传入 handle 的 input |
|---|---|---|
| History 单条右键 | allow-custom-single-history-mutate(用于history右键(单选)) | 单个 id, 如 "1287" |
| History 多选右键 | allow-custom-multiple-history-mutate(用于history右键(多选)) | 逗号拼接 id, 如 "1287,1290,1305" |
前端在
onOpenFuzzerModal事件里: 单选text = \${rowData.Id}`, 多选text = selectedRowKeys.join(','), 同时携带脚本声明的params`(cli 参数)。
拿到 id 后, 用 db 的 Yield 通道反查数据包、再做提取:
handle = func(input) {
ids = parseIds(input) // "1287,1290" -> [1287, 1290]
for flow in db.QueryHTTPFlowsByID(ids...) { // Yield 通道, 底层 yakit.YieldHTTPFlows
host = hostOf(flow.Url)
for f in db.QueryHTTPFlowsByKeyword(host) { // 该 host 的全部历史流量
req = codec.StrconvUnquote(f.Request)~ // flow.Request 是 quote 后的, 需还原
// ... 提取 path / 参数名 / cookie
}
}
}
进度条: yakit.SetProgress
提取量大时, 用 yakit.SetProgress(0~1) 在执行面板显示进度(SetProgressEx(id, f) 可多条):
total = len(hosts); done = 0
for host in hosts {
yakit.SetProgress(float(done) / float(total)) // 注意 yak 的 for i,v in slice 给的是(元素,nil), 索引要自己数
// ... 提取
done++
}
yakit.SetProgress(1.0)
完整可运行: examples/codec-history-extract-paths.yak (
yak <file>自测纯逻辑;--real <id>用真实 History 跑 flow id -> 数据包 -> 提取全链路)。
8. codec 插件 + cli 参数(让用户选"提取什么")
codec 插件也能声明 cli 参数: History 右键时 Yakit 会先弹出参数表单, 用户填完再执行 handle。
用 cli.StringSlice + setSelectOption + setMultipleSelect(false) 做一个"提取项"下拉:
MODE_SEL = cli.StringSlice("mode",
cli.setVerboseName("提取项"),
cli.setSelectOption("提取 Path", "path"),
cli.setSelectOption("提取 参数名", "param"),
cli.setSelectOption("提取 Cookie", "cookie"),
cli.setMultipleSelect(false), cli.setDefault("path"))
cli.check()
MODE = "path"
if len(MODE_SEL) > 0 { MODE = MODE_SEL[0] }
handle = func(input) { // input 仍是 flow id; MODE 由表单决定提取什么
// ... 按 MODE 提取, 可选 db.SavePayload 落字典, db.YieldPayload 回读复用
}
完整可运行: examples/codec-cli-extract-selector.yak (三种模式自测 + Payload 字典
SavePayload/YieldPayloadroundtrip;--real <id> --mode param跑真实库)。 cli 参数体系详见 yakit-native-plugin。
9. Web Fuzzer 选区做"奇怪变换"
在 Web Fuzzer 选中一段(如 payload), 右键 -> 插件扩展 -> codec 插件, input 是选中文本,
可做任意变换返回。一个实用例子: 逐字符混合编码(url %xx / html &#d; / unicode \uXXXX / 原文交替),
得到"语义等价但形态怪异"的变体探测/绕过简单 WAF:
handle = func(input) { return weirdTransform(input) } // "admin" -> a%64m\u0069n
完整可运行: examples/codec-fuzzer-transform.yak。 选区"编码成 fuzztag 并替换"用浮动条编码(见第 5 节 B); 跑复杂变换用右键插件扩展。 提示:
log.info是 printf 风格, 打印含%的内容要用log.info("%s", x)占位, 不能直接字符串拼接。
10. 示例 (examples/)
| 文件 | handle 作用 | input | 验证 |
|---|---|---|---|
| codec-base64-wrap.yak | 选中文本 Base64 编码 | 选中文本 | --input "admin:123456" |
| codec-jwt-decode.yak | JWT 一键解码 header+payload | 选中文本 | --input "eyJ...header.eyJ...payload.sig" |
| codec-unicode-unescape.yak | \uXXXX 还原中文 | 选中文本 | --input '\u4e2d\u6587abc' |
| codec-timestamp-to-date.yak | Unix 时间戳转 UTC 日期 | 选中文本 | --input "1700000000" |
| codec-history-extract-paths.yak | flow id 反查包 -> 提取 host 全部 path/参数名(进度条) | flow id | yak <file> / --real 1 |
| codec-cli-extract-selector.yak | codec + cli 下拉选提取 Path/参数名/Cookie + 落字典 | flow id + cli | yak <file> / --real 1 --mode param |
| codec-fuzzer-transform.yak | Web Fuzzer 选区逐字符混合编码变换 | 选中文本 | --input "<script>alert(1)</script>" |
每个示例都带 YAK_MAIN 自测块, yak <file>.yak 即可自证; 编辑器选区类示例能被
yak codec-plugin 命令复现证据。History 提取类示例用合成数据自测纯逻辑, --real <id> 可跑真实库链路。
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/yaklang/yak-skills/yakit-rightclick-plugin">View yakit-rightclick-plugin on skillZs</a>