yakit-rightclick-plugin について
yakit-rightclick-pluginは、Yakitのcodecプラグインを作成・利用するためのスキルです。`handle(input)`の契約、右クリックメニューへの登録、CLIでの検証方法を説明します。
主な機能
- 01`handle(input)`エントリーポイントの実装
- 02codecプラグインのコンテキストメニュー登録
- 03選択テキストをプラグイン入力に使用
- 04HistoryのフローIDの処理
- 05`yak codec-plugin`による検証
活用シーン
- 01エディターで選択したテキストのエンコードやデコード
- 02Web Fuzzerの選択範囲の変換
- 03Historyのフローからパスやパラメーターを抽出
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ yaklang/ yak-skills --skill yakit-rightclick-pluginインストール後、Claude Code で/yakit-rightclick-pluginを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
examples/codec-base64-wrap.yakcodec-cli-extract-selector.yakcodec-fuzzer-transform.yakcodec-history-extract-paths.yakcodec-jwt-decode.yakcodec-timestamp-to-date.yakcodec-unicode-unescape.yak詳細
SKILL:Yakit 右クリックプラグイン(codec)の使い方とプログラミング
AI LOAD INSTRUCTION:codec プラグインは、Yakit で「小さなツール」を作るための最も低コストな方法です。必要なのは
handle(input)関数だけです。プラグインの種類をcodecに設定し、「パケットの右クリックに使用」スイッチをオンにすると、MITM/History/Web Fuzzer など、すべての HTTP エディターの右クリックメニューに表示されます。現在選択しているテキストがinputとして渡され、handleの戻り値が表示されます。このページでは、有効化の方法、プログラミングの契約、Web Fuzzer の右クリックメニューにある 2 つの階層、そしてコマンドラインで検証するまでの一連の流れを説明します。
0. 関連ルート
- 総合入口:yak
- ネイティブプラグイン(yak/mitm)と cli パラメーター体系:yakit-native-plugin
- 検証ツールチェーン:yaklang-toolchain(
yak codec-pluginコマンド) - 履歴データの抽出/辞書/パケット送信:yakit-data-extract-plugin
- データベース/Payload 辞書:yaklang-database
- 3 種類のホットリロード: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)の 1 文だけです(SafeCallYakFunction(ctx, "handle", [input]))。CLI と Yakit UI は完全に同じ実行経路を使います。
2. 右クリックメニューに表示する方法(重要:1 つの 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、各種ハッシュ/対称暗号化はすべてcodecにあり、多くの小さなツールは 1 行で実装できます。 - 可逆性を優先する:エンコード/デコード系では、できるだけ
handle(handle(x))を成立させるか、エンコードとデコードを対にして、簡単に切り替えられるようにします。 - 公開する前にセルフテストする:
if YAK_MAIN { runSelfTest() }を記述し、yak file.yakでアサーションを実行します。handleをYAK_MAINで囲まないように注意してください(常に登録されている必要があります)。セルフテストだけをガードブロック内に置きます。
5. Web Fuzzer エディターの右クリック(2 階層のメニュー)
Web Fuzzer のリクエストエディターには、エンコード/デコードやプラグインを呼び出せる操作が 2 種類あります。
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> 可跑真实库链路。