mcpField
Y
yakit-rightclick-plugin

yakit-rightclick-plugin

github.com/yaklang開発10121 回インストール15 週間前に更新
リポジトリ

yakit-rightclick-plugin について

yakit-rightclick-pluginは、Yakitのcodecプラグインを作成・利用するためのスキルです。`handle(input)`の契約、右クリックメニューへの登録、CLIでの検証方法を説明します。

主な機能

  1. 01`handle(input)`エントリーポイントの実装
  2. 02codecプラグインのコンテキストメニュー登録
  3. 03選択テキストをプラグイン入力に使用
  4. 04HistoryのフローIDの処理
  5. 05`yak codec-plugin`による検証

活用シーン

  1. 01エディターで選択したテキストのエンコードやデコード
  2. 02Web Fuzzerの選択範囲の変換
  3. 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.yak
codec-cli-extract-selector.yak
codec-fuzzer-transform.yak
codec-history-extract-paths.yak
codec-jwt-decode.yak
codec-timestamp-to-date.yak
codec-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. 関連ルート

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 プラグインエディターで次の操作を行います。

  1. プラグインの種類として codec を選択します。
  2. **「パケットの右クリックに使用」**スイッチをオンにします。

このスイッチは、実質的に YakScript.Tags に tag を追加します。

スイッチの表示名tag 値効果
パケットの右クリックに使用allow-custom-context-menu-execute右クリック → プラグイン拡張サブメニュー(codec プラグイン)に表示されます
HTTP パケット変形allow-custom-http-packet-mutate右クリック → HTTPパケット変形に表示されます(パケット全体を変形)
単一の履歴レコードを処理allow-custom-single-history-mutateHistory の単一レコードを右クリックしたときに使用できます
複数の履歴レコードを処理allow-custom-multiple-history-mutateHistory の複数レコードを選択して右クリックしたときに使用できます

エディターを右クリックすると、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/YieldPayload roundtrip; --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%64&#109;\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.yakJWT 一键解码 header+payload选中文本--input "eyJ...header.eyJ...payload.sig"
codec-unicode-unescape.yak\uXXXX 还原中文选中文本--input '\u4e2d\u6587abc'
codec-timestamp-to-date.yakUnix 时间戳转 UTC 日期选中文本--input "1700000000"
codec-history-extract-paths.yakflow id 反查包 -> 提取 host 全部 path/参数名(进度条)flow idyak <file> / --real 1
codec-cli-extract-selector.yakcodec + cli 下拉选提取 Path/参数名/Cookie + 落字典flow id + cliyak <file> / --real 1 --mode param
codec-fuzzer-transform.yakWeb Fuzzer 选区逐字符混合编码变换选中文本--input "<script>alert(1)</script>"

每个示例都带 YAK_MAIN 自测块, yak <file>.yak 即可自证; 编辑器选区类示例能被 yak codec-plugin 命令复现证据。History 提取类示例用合成数据自测纯逻辑, --real <id> 可跑真实库链路。

コメント