Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
VulnFanatic-NG — 逆コンパイルされたバイナリの脆弱性を特定するためのBianryNinjaプラグインで、プログラムによるスキャンとLLMサポートの両方を備えています。 | Kitploit
ツール/GitHubGitHub/martyx00/vulnfanatic-ng
静的コード分析 (SAST)脆弱性分析コード分析エクスプロイトリバースエンジニアリングファジングペネトレーションテストハードウェアセキュリティバイナリ解析サプライチェーンセキュリティ学習と教育AI支援リバースエンジニアリング
14152ヶ月前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有
GitHubmartyx00/vulnfanatic-ng

VulnFanatic-NG

逆コンパイルされたバイナリの脆弱性を特定するためのBianryNinjaプラグインで、プログラムによるスキャンとLLMサポートの両方を備えています。

リポジトリを見る

VulnFanatic-NG

LLM支援の脆弱性調査のための Binary Ninja プラグインです。

VulnFanatic-NG はサイドバーパネルを追加し、現在のバイナリをスキャンして、疑わしいコードが実際に脆弱かどうかを LLM(デフォルトではローカルホストの OpenAI 互換モデル、または Anthropic Claude、Google Gemini、Azure OpenAI(LLM バックエンドを参照))に判断させます。主に Binary Ninja の**逆コンパイラ出力(HLIL)**を使用し、必要に応じてアセンブリにフォールバックして、確認された問題のみをコードへのクリック可能な参照付きで報告します。


仕組み

スキャンは最大3つのフェーズで実行されます(フェーズ3はオプトインかつオンラインのみ)。

フェーズ1 — 危険な関数呼び出し

rules/phase1_rules.json で定義された危険な関数の呼び出し箇所を検出します — strcpy、memcpy、sprintf/フォーマット文字列、system、alloca、scanf、コマンド/exec API、弱い RNG、free/delete 系(use-after-free / double-free)、固定バッファへの信頼できない入力の読み込み(recv/read/fread/ReadFile)、SQLインジェクション(sqlite3_exec/mysql_query/PQexec)、無効化された TLS 証明書検証(SSL_CTX_set_verify/curl)、SSRF、不適切な権限管理(setuid/setresgid)、memset/bzero 系、攻撃者が制御する長さとの比較(memcmp/strncmp → 認証バイパス)。対象は C/C++、Win32、および(ベストエフォートの)Rust FFI です。対応範囲には、強化された _chk(FORTIFY)および Annex-K _s バリアントが含まれます。境界付きフォーマット出力関数(snprintf およびそのバリアント)には独自のデフォルト安全ルールがあり、正しいサイズ引数がオーバーフローとして報告されないようになっています。

呼び出し箇所は3つの方法で検出されます: 名前付きシンボルへの直接呼び出し。フォワーディングサンク / PLTスタブを経由する呼び出し(実際の呼び出し元が復元されるため、スタブ経由でのみ到達するインポートも見逃されません)。そして — vulnfanatic.scanIndirectCalls がオフでない限り — Binary Ninja が危険な関数に解決した関数ポインタまたは vtable を介してディスパッチされる間接呼び出し。各呼び出し箇所について、プロシージャ間の逆コンパイラ中心のコンテキストを構築し、トークン上限(デフォルト 100k)に収めます。

  • 呼び出し式とその引数、
  • 呼び出された関数の宣言済みプロトタイプ(Binary Ninja の型情報から取得し、なければ組み込みテーブルから)。モデルが引数をパラメータに正しく対応付けるためのもので、強化された __*_chk や境界チェック付き *_s バリアントは先頭に追加の引数が付くため、フォーマット/サイズ/宛先の位置がずれます。
  • 各呼び出し引数の型とバイトサイズ(バッファ容量)。引数の HLIL 式型から導出されるため、s->buf のような構造体フィールドは s のポインタサイズではなく、そのフィールドの実際の配列サイズに解決されます。型セクションの構造体定義にもフィールドごとのバイトサイズが含まれます。
  • 各引数の具体的な値/範囲。Binary Ninja の定数伝播と値集合解析によって解決されたものです(例: 長さが定数 0x40 であることが証明されたり、[0, 0xff] に制限される)。モデルはサイズをバッファ容量と比較する際に推測ではなくこれを真実として使用します。
  • 呼び出し元関数のスタックフレームレイアウト(変数のオフセットとバイトサイズ)。固定サイズのバッファが含まれる場合に、隣接する変数や保存されたリターンアドレスに対してスタックオーバーフローを判断できるようにするためのものです(vulnfanatic.includeStackLayout)。
  • パス制約(呼び出しをガードする if/ループ/switch 条件)。
  • 引数のデータフローサマリ — 各呼び出し引数が関数内でどこで定義され、どこで使用されるか。
  • 呼び出し元をまたぐパラメータ解決 — 危険な引数が呼び出し元関数のパラメータである場合、各呼び出し元が実際に何を渡しているかをコンテキストが報告します(例: 「すべての呼び出し元が文字列リテラルを渡す」)。これにより、常に定数であるフォーマット/サイズパラメータが攻撃者制御と誤認されるのを防ぎます。
  • 呼び出し元関数の完全な逆コンパイル済み本体。
  • 呼び出しチェーンと引数変数全体で参照される型のデータ型定義(struct/union/enum)。モデルが実際のバッファ/フィールドサイズと整数幅を把握できるようにするためです。

このコンテキストとルール固有のプロンプトがモデルに送信され、モデルは構造化された判定を返します。問題ではないものは破棄されます。プロンプトは強力なローカルコードモデル(例: Qwen2.5-Coder)向けに調整されており、フロー全体を分析して JSON のみを出力するよう指示します。

推論、スクラッチパッド、信頼度

モデルは再現率を優先するよう指示されます。完全に証明できないものを破棄するのではなく、もっともらしいセキュリティ関連の問題を報告し、不確実性は信頼度(Confidence)で表現します。モデルは、判断の根拠となったコードスニペットをそのまま引用するスクラッチパッドに思考過程を示します(入力ソース、各ガード、サイズ/長さ、関連する型、シンク)。これは検出名に保存されるため、推論を監査できます。

各検出名には信頼度(high/medium/low)が付きます。high = コンテキストにチェーン全体が示されている。medium = 可能性が高く、リンクが1、2件推定される。low = 手動レビューに値する手がかり。これは主要な指標です(モデルの重大度推定は副次的なフィールドです)。vulnfanatic.minConfidence を設定すると、しきい値未満のものはすべて破棄されます。

適合率と再現率の調整

デフォルトでは VulnFanatic-NG は再現率を優先します(実際の問題を捕捉)。誤検出が多すぎる場合は、次のいずれかで厳しくします。

  • vulnfanatic.validationPass(デフォルト オフ)— 2回目の LLM パスを実行し、フラグが立った各問題を同じコンテキストに対して再検証します(スクラッチパッドのスニペットを検証し、フローを再トレース)。判定や信頼度を修正できます。フラグが立った候補に対して LLM 呼び出しが2倍になります。
    • 別のバリデータモデル(検証パスを使用する場合に推奨)。 vulnfanatic.validatorModel(および validatorProvider / validatorBaseUrl / validatorApiKey)を設定すると、2回目のパスを別のモデルで実行できます。独立したモデルからのセカンドオピニオンははるかに有用です。盲点が少なく、最初の判定を鵜呑みにする可能性がはるかに低いためです(モデルは自分の答えを好む傾向があります)。良いパターンはカスケードです。アナリストとして高速なモデル(広い再現率)、バリデータとして最も強力なモデルを使用し、バリデータはフラグが立った候補に対してのみ実行されます。バリデータモデルを空白にすると、アナリストモデルで検証します。バリデータはアナリストと同等以上の能力を持つべきです。弱いモデルは誤った却下を増やすだけです。プロバイダー / ベースURL / キー / モデル以外はすべてアナリストの接続設定から継承されます。バリデータキーを空白にするとアナリストキーが再利用され、バリデータエンドポイントに到達できない場合は最初の判定が保持されます(検証の障害で検出名が失われることはありません)。
  • vulnfanatic.minConfidence(デフォルト low)— medium/high に引き上げると、より確度の高い検出名のみを報告します。
  • vulnfanatic.skipConstantArgCalls(デフォルト )— 引数がすべてコンパイル時定数であるオーバーフロー系の呼び出し箇所をスキップします。

速度。 呼び出しごとのレイテンシのほとんどは書かれる推論によるものなので、vulnfanatic.verdictReasoning がモデルの出力量を制御します。

  • concise(デフォルト)— 1〜3文の簡潔な根拠。コードの逐語引用なし。full よりもはるかに高速で、精度の低下はわずかです。vulnfanatic.maxResponseTokens を下げることもできます。
  • full — 引用スニペット付きの詳細なスクラッチパッド(最も監査しやすく、最も遅い)。
  • none — 判定のみ。最速。推論対応バックエンド(vulnfanatic.reasoningEffort)と組み合わせると、モデルの内部思考が作業を担います。素のローカルモデルでは none は精度を失います(思考連鎖がまったくないため)。

常に有効な精度サポート機能(検出名を抑制せずにモデルに情報を提供します):

  • 引数の由来(Argument provenance) — コンテキストは、各引数がコンパイル時定数、関数パラメータ、汚染ソース由来のいずれであるかをモデルに伝えます。モデルはこれを信頼度の設定に使用します。
  • 境界チェック付きバリアントの認識 — プロンプトは _s(Annex K)と _chk(FORTIFY)バリアント、および長さ制限付き API を、サイズ引数自体が誤っていない限り安全として扱います。
  • 明示的なバッファサイズ — 引数と構造体フィールドのバイト容量が提供されるため、モデルは推測ではなく容量と書き込まれるバイト数を比較できます。

オフラインスキャン(LLMなし)

Scan Offline ボタンは、モデルなしでフェーズ1を実行します — phase1_rules.json の各ルールの offline ブロックで宣言された純粋にプログラム的なヒューリスティックです。危険な呼び出し箇所にフラグを立て、明らかに安全なものは除外し、ヒューリスティックな信頼度を割り当てます。

  • 除外(Eliminated)(報告されない): 定数長の memcpy/memmove、定数文字列からの strcpy、定数フォーマットの printf、定数コマンドの system など — 支配的な引数がコンパイル時定数であり、攻撃者によって制御され得ない呼び出しです。「定数」には、Binary Ninja の値集合解析が上流で固定値に特定した値も含まれ、リテラル引数だけではありません。
  • High 信頼度: 実行フロー上のどこにも緩和チェックが見つからずにフラグが立てられたもの。
  • 降格(Downgraded)(→ medium): サイズ/長さ引数が Binary Ninja の値集合解析によって定数/有界範囲に解決されたか、関連する引数を比較する実際の境界/検証チェック(例: strlen/サイズ比較、if (len < …))がフロー上のどこか — パス上で呼び出される関数内を含む — で見つかった場合。すでに処理されている可能性があります。(変数に言及するだけで比較しない分岐はもはやカウントされず、誤った降格の原因が取り除かれます。)

ヒューリスティックは、ルール内の小さな宣言的ボキャブラリ(constant_safe_args、eliminate_if_all_args_constant、format_arg_lookup、length_guard_vars、base_confidence、skip)を使用し、Python 述語によって評価されます — exec する埋め込みコードはありません。ほとんどのルールにはオフライン定義があります(オーバーフロー、フォーマット文字列、コマンド実行、scanf、パス処理、弱い RNG、弱い数値解析、権限変更、アロケーションサイズなど)。本当に意味解析が必要な2つのカテゴリだけがオフラインではスキップされ、LLM に委ねられます: free/delete 系(use-after-free / double-free。ポインタのライフタイム追跡が必要)とTLS検証(バグは SSL_VERIFY_NONE のような特定の定数値です)。オフラインサマリは、いくつのサイトがフラグ立て / 除外 / スキップ(LLM が必要)/ 失敗したかを報告するため、カウントは合計されます。これは高速なトリアージです。実際の判断 — およびスキップされたカテゴリ — には、完全な LLM スキャンを実行してください。

オフラインの検出名も、オンラインスキャンが送信するのと同じ完全なプロシージャ間コンテキストを(フラグが立ったサイトのみ)構築して保存するため、トリアージ後はオンラインの検出名と同様にファインチューニング用データとしてエクスポートできます。オフラインの速度を最大化したい場合は、vulnfanatic.offlineBuildContext で無効にします。

フェーズ2 — セキュリティ関連コード(シンボルゲート)

バイナリに実際のシンボル / 変数名があると思われる場合にのみ実行されます。rules/phase2_rules.json で定義されたセキュリティ関連関数を特定します — 認証、暗号化(弱いアルゴリズムを含む)、署名/証明書検証、セッション/トークン処理、アクセス制御、秘密/キー処理、入力検証、非定数時間の秘密比較、安全でないデシリアライゼーション — 関数名と参照される文字列で照合し、モデルが監査します。

フェーズ3 — ハードウェア攻撃耐性監査(オンライン、オプトイン)

ファームウェア堅牢化の監査で、フォールトインジェクション(電圧/クロック/EMグリッチング)およびサイドチャネル(タイミング/電力)攻撃に対するもので、ハードウェア攻撃の緩和ガイダンスに基づいています。バグを見つけるフェーズ1〜2とは異なり、フェーズ3はセキュリティ上重要な関数における欠落または違反した堅牢化コントロールを報告します — 例: デフォルトフェイル分岐、二重チェックされたセキュリティ判断、ループ後のカウンタ検証、高ハミング距離の状態定数(単純な 0/1 ではなく)、定数時間の全長シークレット比較、ランダムオフセットでのシークレットアクセス/消去、暗号化してから検証(anti-DFA)、制御フロー整合性カウンタ、ユーザーランド暗号の回避、生の鍵素材を直接扱わないこと(rules/phase3_rules.json)。

コンパイラの最適化によってソースレベルの保護が削られる可能性があるため、これらのコントロールはコンパイル済みバイナリで検証するのが最適です — まさにこれがチェックするものです。フェーズ3はLLMのみ(オンライン)、シンボルゲート、デフォルトでは無効です。New Scan タブの Phase 3 チェックボックスでスキャンごとに有効にします(オフラインモードでは実行されません)。

検出名はテーブル(ステータス、信頼度、フェーズ、CWE、関数、アドレス、タイトル)に一覧表示され、詳細ペインには説明、分析スクラッチパッド、検証ノートが表示されます。行をダブルクリックすると、バイナリビューがコードに移動します。

トリアージワークフロー

すべての検出名は Untriaged で始まります。行を右クリックしてステータスを設定します — Mark as Real Issue、Mark as False Positive、または Mark as Untriaged。ステータスを変更するたびに "Provide reason:" テキストボックスがポップアップします(理由は検出名とともに保存されます)。テーブルはステータスを明確に示します: Real Issues は緑/太字で上部にソートされ、False Positives はグレー/取り消し線で下部にソートされ、Untriaged はその間に信頼度の色付きで表示されます。サマリ行に件数が表示されます。

各結果タブには Export triaged (fine-tuning)… ボタンがあり、トリアージ済みの検出名(Real Issue + False Positive)のみをファインチューニング用の OpenAI チャット形式 JSONL としてエクスポートします。各サンプルは、元の system+user プロンプトと人間が修正した判定をアシスタントターゲットとしてペアにします(False Positive は is_vulnerable=false とあなたの理由を教え、Real Issue は is_vulnerable=true を強化します)。これにより、あなたのバイナリに対するモデルの精度を反復的に改善できます。

詳細ペインに表示される(およびファインチューニングプロンプトの再構築に使用される)検出名ごとのコンテキストは、デフォルトでは完全な状態で保持されます — vulnfanatic.storedContextChars で制御します(0 = 無制限。正の上限(例: 4000)を設定すると、コンテキストの忠実度を犠牲にして BNDB の肥大化を抑えられます)。

複数スキャン(タブ)

パネルはタブ形式です。最初のタブは常に New Scan で、次の項目を設定します:

  • オプションのスキャン名(空白 → <timestamp> <mode>、例: 2026-06-15 14:03:50 offline)、
  • オプションのフェーズ1 / フェーズ2 / フェーズ3 カスタムルールパス(空白 → バンドルされたデフォルト)。代替ルールセットを実行できます、
  • Phase 3 チェックボックス(デフォルトではオフ)。オンライン限定のハードウェア攻撃耐性監査を追加実行します。

その後、Start Scan または Scan Offline を押します。実行ごとに独自の結果タブが開き、検出名がライブでストリーミングされます。すべてのスキャンは BNDB に保存されます。たとえば、オフラインスキャンを保持して後でオンラインスキャンを追加したり、異なるルールセットでの実行を並べて比較したりできます。データベースを再度開くと、それらはタブとして再表示されます。タブを閉じると、そのスキャンは BNDB から完全に削除されます。事故を防ぐため、Delete results forever ボタンが有効になる前に、「 の結果を永久に失うことを確認します。」 にチェックを入れる必要がある確認ダイアログがポップアップします。Export current scan… は選択中のタブを Markdown/JSON に書き出します。

開いている各バイナリは独立したパネル状態を持ちます — 独自のスキャンタブと実行中のスキャン。あるバイナリでスキャンを開始して別のバイナリに切り替えると、2番目のバイナリの結果が表示され(個別にスキャンも可能)、最初のバイナリのスキャンはバックグラウンドで実行され続け、切り替えて戻るとそのまま残っています。


インストール

このプラグインのパッケージフォルダ名は vulnfanatic_ng です(有効な Python 識別子です。Binary Ninja はプラグインフォルダ名をモジュールとしてインポートするため、VulnFanatic-NG のようなハイフン付きの名前は読み込まれません)。

  1. (オプション)正確なトークンカウントを Binary Ninja の Python にインストールします: ``` pip install tiktoken

    root@kitploit:~
  2. vulnfanatic_ng フォルダを Binary Ninja のユーザープラグイン ディレクトリにシンボリックリンクするかコピーします:

    • macOS: ~/Library/Application Support/Binary Ninja/plugins/
    • Linux: ~/.binaryninja/plugins/
    • Windows: %APPDATA%\Binary Ninja\plugins\

    例えば、macOS の場合: ``` ln -s "$(pwd)/vulnfanatic_ng" "$HOME/Library/Application Support/Binary Ninja/plugins/vulnfanatic_ng"

    root@kitploit:~
  3. Binary Ninja を再起動するか(または Reload Plugins を実行)します。右サイドバーに VF アイコンが表示されます。


設定

設定(歯車アイコン / Edit ▸ Preferences ▸ Settings)を開き、vulnfanatic を検索してください。最低限、以下を設定します:

LLM バックエンド

vulnfanatic.apiProvider は、リクエストの構成方法と認証方法を選択します。判定コントラクト(およびすべてのルールプロンプト)はプロバイダ間で同一です。

AWS Bedrock は、その OpenAI 互換エンドポイントを介して openai プロバイダ経由で使用できるため、専用のバックエンドは不要です。

その他の便利な設定: vulnfanatic.maxContextTokens(既定 100000)、 vulnfanatic.maxResponseTokens、vulnfanatic.temperature、 vulnfanatic.reasoningEffort(off/low/medium/high。既定 high — サポートされている場合、 モデルは回答前に考えるよう要求されます。プロバイダごとに以下へマップされます: openai/azure は reasoning_effort、anthropic は適応的思考 + output_config.effort、 google は動的 thinkingConfig。モデルが拒否した場合は自動的に除去して再試行します)、 vulnfanatic.requestTimeoutSec、 vulnfanatic.callPathMaxDepth / vulnfanatic.callPathMaxPaths、 (コールパス上の関数の逆コンパイル済み本体を含める、 既定 on)/ (上限、既定 12)、 (パス上で呼び出される他の関数も含めます。これらは 境界/検証チェックを持つ可能性があります。既定 on)/ (上限、既定 12)、 (struct/union/enum 定義を含める。既定 on)/ (上限、既定 24)、 (呼び出し引数をその生成元/消費元まで遡って追跡し、 それらの本体を含めます。既定 on)/ (上限、既定 8)、 (呼び出し元関数に固定サイズのバッファがある場合、そのスタック変数レイアウトを 含めます。既定 on)、 (解決された関数ポインタ/vtable を経由してディスパッチされる危険な呼び出しも 一致させます。既定 on — 非常に大きなバイナリではスキャンを高速化するため off にします)、 (2 回目のダブルチェックパスを実行。既定 off)/ / / / (検証パスを 別の独立したモデルで実行 — 空欄 = 分析モデルと同じモデル)/ (//。これ未満の検出結果は破棄。既定 )、(モデルがスコア付けできなかったサイトを破棄せず、 信頼度の "Unscored" 候補として報告。既定 on)、 (全引数が定数のオーバーフロー呼び出しサイトをスキップ。 既定 off)、(//。判定ごとにモデルが書く 推論の量 — 主な速度調整レバー。既定 )、 / / (各フェーズを有効化。Phase 3 は オンライン専用で、通常はここではなく New Scan チェックボックスでスキャンごとに切り替えます)、 / 、 (トークン見積もりのための tiktoken エンコーディング。tiktoken が インストールされていない場合は文字ヒューリスティックにフォールバック)、 (オフライン検出結果用に完全なコンテキストを構築し、ファインチューニング用に エクスポートできるようにします。既定 on)、 (コンソールへの詳細なパイプライントレース。既定 off)/ (バイナリを特定できるすべての詳細を編集し、ログを 共有可能にします — 下の を参照)、 、(HTTPS 証明書を 検証。既定 on)/ (HTTPS 用 CA バンドル — が発生した場合は Troubleshooting を参照)、および / / (これらを独自のルールファイルに指定して、 検出とプロンプトをカスタマイズします)。

セキュリティ上の注意: API キーは Binary Ninja の設定に平文で保存されます。 機密キーには環境変数による上書きを推奨します。

テストモード(ドライラン、LLM なし)

vulnfanatic.apiBaseUrl をリテラル値 TEST に設定すると、LLM なしで実行できます:

  • モデルは決して呼び出されません(ネットワーク不要、API キー/モデルも不要)。
  • すべての候補(Phase 1 の各危険な呼び出しサイト、Phase 2 の各 セキュリティ関連関数)がフラグ付けされます。
  • 各候補の完全なプロンプト — システムプロンプト および完全に生成されたコンテキスト — が、 次のディレクトリ配下の専用ファイルに書き込まれます: /tmp/vulnfanatic_ng/<binary>-<timestamp>/。
  • 検出結果テーブルに Prompt File 列が表示され(フルパスはホバーで表示)、 詳細ペインとエクスポートにもパスが含まれます。

これを使用して、VulnFanatic-NG がモデルに送信する正確な内容を検査・検証し、モデル時間を消費せずにルールプロンプト/コンテキストを反復調整できます。

デバッグログ

vulnfanatic.debugLogging をオンにすると、スキャンパイプラインの詳細なステップバイステップのトレースが (オンライン/オフラインの両方)Binary Ninja のログ/コンソールに出力されます: 各呼び出し サイト、すべてのスキップ/除外決定、コンテキスト構築(サイズのみ)、各 LLM リクエスト (プロバイダ/モデル/エンドポイント、リトライ、フォールバック)、各判定、および報告された各 検出結果。API キーがログに記録されることはありません。

デバッグログがオンの間、オンラインスキャンでは、確定された問題にならない候補を破棄せず、すべての候補を結果 テーブルに保持します。各候補には デバッグ専用ステータスがタグ付けされます(暗転表示され、下部にソートされます):

  • REJECTED — LLM が 問題なし という判定を返した。
  • SKIPPED — 証明可能な安全ルール(定数フォーマット文字列、または全引数が定数)によって LLM の前に除外された。行にはその理由が表示される。
  • ERROR — 候補を分析できなかった(コンテキスト構築の失敗、LLM 応答が解析不能、または接続失敗)。行にはエラーが表示される。

したがって、デバッグスキャンでは /N 合計のうち候補ごとに 1 行が表示され、サマリーは 問題数と rejected/skipped/error 数を別々に報告します。これらの行は右クリックして Real Issue または False Positive として再トリアージできます(ファインチューニング用エクスポートの対象になります)。 (オフラインスキャンは影響を受けません — LLM を呼び出すことはありません。)

デバッグモードとは無関係に、モデルが解析不能な応答を返した場合 — 例えば Gemma の <unused…> のような迷子トークン、JSON の代わりに散文、または 空メッセージ(role のみで content がない場合)— クライアントは 1 回の修正リトライを行い、構造化出力フォーマットを無効にして JSON のみを 再要求します。成功した場合、スキャンの残りはそのフォーマットを無効にしたままにします。 また、クライアントは content が空のとき 推論チャネル (reasoning_content / reasoning)も読み取るため、回答をそこに置く推論モデルでも 機能します。

空メッセージのケースは、OpenAI 互換 API(例: mlx-community/gpt-oss-20b)で提供される GPT-OSS / o1 などの推論モデルでよく発生します: response_format=json_object が設定されていると、 harmony の「final」回答チャネルが抑制されることが多く、 サーバーは content なしで {"role": "assistant"} を返します。これらのモデルはまた、 出力予算のすべてを推論チャネルに使い切り、思考途中で切り詰められ、 JSON を一切含まない散文を返すことがあります。自動リトライはフォーマット関連のケースを回復します。 それでも続く場合は、vulnfanatic.sendJsonResponseFormat をオフにし、vulnfanatic.reasoningEffort を下げ (思考に使う予算を減らす)、および/または vulnfanatic.maxResponseTokens を上げてください。 一方、<unused…>/意味不明な応答が続く場合は通常、 プロンプトがモデルのコンテキストウィンドウを超えている(vulnfanatic.modelContextWindow を設定し、 および/またはサーバーのコンテキスト長を上げる)、またはモデルが厳密な JSON 出力に不向きである (Qwen2.5-Coder のようなコードモデルは Gemma よりはるかに優れた動作を示します)ことを意味します。

リコールを保持するフォールバック。 リトライ後も候補をスコアリングできない場合、 vulnfanatic.flagUnparseableResponses(既定 on) はそれをとにかく "Unscored" 検出結果として UNKNOWN 信頼度で報告します — low とは異なる値です( モデルは判定を生成しなかったため、低信頼度の判断ではありません)。これは下部にソートされ、 モデルの部分出力を説明として保持するため、サイトを失わず、 手動でレビューするだけです。オフにすると、代わりにそのようなサイトは破棄されます(その後は 分析エラーまたはデバッグの ERROR 行としてのみ表面化します)。

また、vulnfanatic.debugAnonymous を有効にすると、ログを共有しても安全になります: 分析対象ファイルを特定できるすべての情報を編集します — シンボル/変数名と アドレスは実行ごとのソルト付きハッシュになります(実行内では一貫しているため、フローは 追跡可能)、ファイル名は隠され、検出結果テキストは <redacted> に置き換えられ、 LLM エンドポイントのホストはハッシュされ、逆コンパイルされたコード / プロンプト / コンテキストは サイズのみがログに記録されます(内容は決して記録されません)。これにより、バイナリに関する 情報を開示せずに、問題を報告するためのデバッグログを送信できます。


使い方

  1. バイナリを開き、解析が完了するまで待ちます。
  2. サイドバーの VF アイコンをクリックして VulnFanatic-NG を開きます。
  3. Start Scan(完全な LLM スキャン)または Scan Offline(高速で LLM を使わない プログラム的な Phase 1 — 上記参照)を押します。進行状況はパネルと Binary Ninja のステータスバーに表示されます。検出結果はライブで表示され、キャンセルできます。
  4. 検出結果をクリックして説明を読み、ダブルクリックでコードにジャンプします。
  5. 検出結果を右クリックして Mark as false positive にします — テーブルの下部に移動し、 グレーアウトされて取り消し線が付き、メニュー項目は Mark as real issue に変わって元に戻せます。(右クリックメニューには Go to code もあります。)
  6. Markdown または JSON にエクスポートするか、Clear で保存済みの検出結果を破棄します。

検出結果は、誤検知ステータスを含めて、Binary Ninja データベースに保存されます。データベースを保存すると .bndb に書き込まれ( .bndb が既に存在する場合は即座にフラッシュされる)、再オープン後も保持されます。

スキャンは一致したすべての呼び出しサイト(上限なし)を分析するため、ローカルモデルに適しています。 ホスト型/従量課金エンドポイントの場合は、大規模な バイナリではボリュームに注意してください。


ルールのカスタマイズ

両方のルールファイルは、共通の system_prompt と output_schema、および rules のリストを含むエンベロープを共有します。 バンドルされたファイルをコピーし、関数/キーワード/プロンプトを編集して、 vulnfanatic.rulesPhase1Path / vulnfanatic.rulesPhase2Path をコピー先に指定します。 Phase 1 ルールは functions(完全一致)と name_regex でマッチし、Phase 2 ルールは name_keywords、name_regex、 string_keywords でマッチします。各ルールの prompt は {function} プレースホルダーを使用できます。


モデルのファインチューニング(MLX、Apple Silicon)

トリアージ済みエクスポートは、そのままモデルにフィードバックできるように設計されています。 複数のバイナリにわたって検出結果をトリアージし、それぞれで Export triaged (fine-tuning)… をクリックした後(.jsonl ファイルを 1 つのフォルダに収集)、 scripts/finetune_mlx.py がそれらに対して MLX LoRA ファインチューニングを実行します。```bash pip install mlx-lm # Apple Silicon / macOS

Fine-tune a local 4-bit model on every *.jsonl under ./exports

python scripts/finetune_mlx.py ./exports
--model mlx-community/Qwen2.5-Coder-7B-Instruct-4bit
--adapter-path ./vf-adapters --iters 800

...then fuse the adapters into a standalone model

python scripts/finetune_mlx.py ./exports --model
--fuse --fused-path ./vf-qwen-coder-vuln

root@kitploit:~
スクリプトは位置引数として**training-dataフォルダ**とベースの
**`--model`** (ローカルパスまたはMLX/HFリポジトリID) を受け取ります。その他のパラメータはオプションです:
`--adapter-path`, `--valid-split` (0.1), `--iters`, `--batch-size` (小さな分割に
収まるよう自動的にクランプされます), `--num-layers`, `--learning-rate`, `--max-seq-length`
(`0` = 最長の例に**自動調整** (上限16384)。正の値を設定すると
その値に固定されます), `--fine-tune-type` (`lora`/`dora`/`full`), `--seed`, `--fuse`/`--fused-path`,
および`--dry-run` (トレーニングせずにデータを準備してコマンドを表示します)。リテラル
`--`の後にあるものはすべて、そのまま`mlx_lm lora`に転送されます。フォルダ内のすべての
`*.jsonl`を再帰的にマージし、チャットの例を検証して**重複排除**し、MLXが期待する
`train.jsonl`/`valid.jsonl`の分割を作成してから、`python -m mlx_lm lora`
(`--fuse`付きの場合は`mlx_lm fuse`も) を起動します。

結果はOpenAI互換サーバー (`mlx_lm.server --model <path>`) で公開し、
`vulnfanatic.apiBaseUrl`をそのサーバーに向けて、チューニングしたモデルでスキャンしてください。

> VulnFanatic-NGのコンテキストは大きいため、デフォルトではスクリプトは`--max-seq-length`を
> 最長の例に**自動調整**します (切り上げ、上限**16384トークン**)。
> 長いシーケンスはトレーニングメモリを大量に消費するため、この上限に近い大きなモデルは
> 小さなMacのメモリを不足させる可能性があります。例が上限を超える場合は切り詰められます。
> エクスポートする前に、より高い`--max-seq-length`を渡すか (メモリ増加)、
> `vulnfanatic.storedContextChars`を低くしてください。トレーニングがシグナル (例: `exit -10` / SIGBUS) で
> 終了した場合はメモリ不足によるクラッシュです。`--max-seq-length`を下げるか、
> `-- --grad-checkpoint`を追加するか、より小さなモデルを使用してください。

---

## 開発とテスト

このプラグインには必須のサードパーティ依存関係はありません。純粋なモジュール
(`rules`, `tokens`, `llm`, `findings`, `settings`, `prototypes`) は、Binary Ninjaもネットワークも
必要としないオフラインのテストスイートでカバーされています。`tests/`
スイートはプロジェクトのソースリポジトリにあります (公開されたプラグインには同梱されていません)。
そこから実行してください。パッケージディレクトリからでも、すべてのモジュールの
構文チェックが可能です:```
python3 -m py_compile *.py ui/*.py
python3 -m unittest discover -s tests   # from the source repository

Binary Ninja 向けモジュール(context_builder、phase1、phase2)は、Binary Ninja なしでも問題なくインポートできます(API アクセスはガードされています)が、実際に動作させる には実行中の Binary Ninja が必要です。

Binary Ninja 内での手動テスト

  1. 小さな脆弱な C プログラムをビルドします(例:argv[1] を固定サイズの スタックバッファに strcpy し、入力に対して system() を呼び出すもの)。 Phase 2 もテストするため、シンボル付きでコンパイルしてください。
  2. ローカルの OpenAI 互換サーバーを起動し、vulnfanatic.apiBaseUrl、 vulnfanatic.apiKey、vulnfanatic.model を設定します。
  3. バイナリを開き、Start Scan を実行して、危険な呼び出しが報告されることと、 ダブルクリックで呼び出し箇所に移動することを確認します。

トラブルシューティング

SSL: CERTIFICATE_VERIFY_FAILED ... unable to get local issuer certificate — HTTPS エンドポイントの証明書自体は正常ですが、Binary Ninja に同梱されている Python には 検証用の CA バンドルがありません(macOS や組み込み Python でよく発生します。AWS Bedrock、 Anthropic、Google、Azure などのホスト型エンドポイントでも発生します)。以下を優先順に 試して修正してください:

  • certifi をインストールする:Binary Ninja が使用する Python に pip install certifi でインストールします。VulnFanatic-NG は自動的に検出して使用します。
  • CA バンドルを指定する: vulnfanatic.caBundlePath にバンドルファイル(または ディレクトリ)を設定します — 例:python3 -m certifi が出力するパス、または /etc/ssl/cert.pem。
  • 最終手段: vulnfanatic.tlsVerify をオフにする(信頼できる内部エンドポイントまたは 自己署名のローカルサーバーにのみ使用してください — これにより証明書チェックが無効に なります)。

HTTP 400 ... tokenizer.chat_template is not set — 配信中のモデルにチャットテンプレート がないため、/chat/completions エンドポイントがメッセージをフォーマットできません。 VulnFanatic-NG はこのエラーを検出すると、スキャンの残りを /completions エンドポイントに 自動的にフォールバックするため、スキャンは継続されます。最初の失敗リクエストを完全に 回避するには、vulnfanatic.apiMode を completions に設定します。あるいは、チャット テンプレートを同梱したモデルを配信するか、サーバーにテンプレートを渡してサーバー側で修正 します — 例:vLLM の場合は --chat-template <template.jinja>(または -Instruct/-Chat 系のモデルバリアントを使用)。専用のチャットテンプレートは通常、フラット化された completions プロンプトよりも良い結果をもたらします。

No JSON object found ... response looks truncated — モデルの応答が JSON の完了前に 途切れています。原因は2つあります:

  • スクラッチパッドが応答予算を超過した → vulnfanatic.maxResponseTokens を引き上げます。
  • より一般的な原因: プロンプトがモデルのコンテキストウィンドウを埋め尽くし、生成する 余地がなくなるため、maxResponseTokens をいくら高く設定しても応答は数トークンで止まります。 ローカルサーバーはウィンドウが小さいことがよくあります(ollama はデフォルトで num_ctx=2048!)。vulnfanatic.modelContextWindow をサーバーのウィンドウに合わせて 設定することで修正できます(例:ollama の num_ctx、llama.cpp の -c、vLLM の --max-model-len)。これにより VulnFanatic-NG は送信するコンテキストを自動的に制限し、 プロンプト + 応答が収まるようにします。また、vulnfanatic.maxResponseTokens は妥当な値 (≈8192、65535 ではなく)に保ち、必要に応じてサーバーのウィンドウも引き上げてください。 小さすぎるウィンドウ(≤8k)では完全なプロシージャ間コンテキストを保持できないため、32k 以上 に設定されたモデル/サーバーを使用してください。

IncompleteRead / Could not complete request ... after N attempt(s) — サーバーはリクエストを受け付けましたが、完全な応答を送信する前に接続を閉じました。 これはほとんどの場合、モデルサーバーが生成中にクラッシュまたは停止したことを意味します: メモリ不足(大きなコンテキスト + 長い出力)、内部/ワーカーのタイムアウト、またはプロキシに よる接続リセットです。VulnFanatic-NG は自動的に1回再試行し、その後そのサイトをスキップ します。実際の原因についてはモデルサーバー自身のログを確認してください。 vulnfanatic.maxContextTokens や vulnfanatic.maxResponseTokens を減らすか、サーバーに より多くのメモリ / より大きなコンテキストウィンドウを割り当てることで、通常は解決します。

制限事項

  • Phase 2 はシンボルを認識します。 ストリップされたバイナリでは名前ベースのマッチは 信頼できないため、デフォルトでは文字列エビデンスルールのみが実行されます(特徴的な 文字列定数を参照する関数は引き続き監査可能です)。名前ベースのマッチも監査するには vulnfanatic.phase2ForceEnable を設定するか、vulnfanatic.phase2RequireSymbols=off にします。シンボルゲートはヒューリスティックです。
  • HLIL ↔ コールサイトのマッピングが失敗することがあります。その場合 VulnFanatic-NG は MLIL/アセンブリにフォールバックし、検出結果ごとに使用した表現を記録します。
  • 判定結果はモデルの性能に依存します。検出結果は手動レビューの手がかりとして扱い、 絶対的な真実(ground truth)としては扱わないでください。
  • 一部のローカルサーバーは response_format=json_object を無視または拒否します。クライアント はそれを許容し、JSON の抽出を継続します。サーバーがパラメータを完全に拒否する場合は vulnfanatic.sendJsonResponseFormat を無効にしてください。

ライセンス

Apache-2.0(© Martin Petran)— plugin.json を参照してください。

ツールをダウンロード
  • 呼び出しの引数変数を生成または消費する関数の逆コンパイル済み本体(HLIL の def/use で追跡)。これにより use-after-free / double-free や汚染サイズの推論が可能になります。
  • エントリポイント / エクスポートされた関数から呼び出しまでの呼び出しパス。
  • それらの呼び出しパス上のすべての関数の逆コンパイル済み本体(危険な呼び出しに最も近いものから順に)。各関数には呼び出し箇所と次のホップをガードする条件が注釈付けられます。
  • パス上の関数が呼び出す他の関数の本体(例: MAIN→ABCD→strcpy の場合、MAIN と ABCD が他で呼び出す関数も含む)。危険な値を制御する境界/検証チェックが含まれている可能性があるためです(vulnfanatic.includeCallPathSiblings。予算が許す限り追加されます)。
  • 汚染ソースのヒント(同じ関数内で呼び出される recv/read/getenv などの入力関数)。
  • オフ
    設定意味
    vulnfanatic.apiProvider呼び出す LLM バックエンド: openai(既定)、anthropic、google、azure。下の LLM バックエンド を参照。すべてのプロバイダは Python 標準ライブラリ経由でアクセスされるため、pip install は不要です。
    vulnfanatic.apiBaseUrl選択したプロバイダのエンドポイントベース(下の表を参照)。既定は http://localhost:8080/v1。リテラル値 TEST に設定すると テストモード が有効になります(下記参照)。
    vulnfanatic.apiKeyAPI キー / ベアラートークン。ローカルサーバーでは空でも可。VULNFANATIC_API_KEY または OPENAI_API_KEY 環境変数で上書きされます。
    vulnfanatic.model必須(テストモードを除く)。モデル識別子(azure の場合は デプロイメント名)。
    vulnfanatic.apiModeopenai のみ: chat(既定、/chat/completions)と completions(単一のフラット化されたプロンプト — チャットテンプレートなしで提供されるベース/インストラクトモデル用)。
    vulnfanatic.azureApiVersionazure のみ: api-version クエリパラメータ(既定 2024-10-21)。
    ProviderapiBaseUrlAuthNotes
    openai例: http://localhost:8080/v1 のような自前サーバーAuthorization: BearerOpenAI 互換の Chat/Completions: ローカルの llama.cpp / ollama / vLLM、OpenAI、および AWS Bedrock の OpenAI 互換エンドポイント。
    anthropic空欄 → https://api.anthropic.comx-api-key + anthropic-versionClaude Messages API(POST <base>/v1/messages)。temperature は送信されません(現在の Claude モデルはこれを拒否するため)。
    google空欄 → https://generativelanguage.googleapis.comAPI キーを URL に含めるGemini generateContent(<base>/v1beta/models/<model>:generateContent)。
    azurehttps://<resource>.openai.azure.comapi-key ヘッダーAzure OpenAI。model には デプロイメント名、azureApiVersion には API バージョンを設定します。
    vulnfanatic.callPathIncludeBodies
    vulnfanatic.callPathMaxBodies
    vulnfanatic.includeCallPathSiblings
    vulnfanatic.callPathSiblingMaxBodies
    vulnfanatic.includeDataTypes
    vulnfanatic.maxTypeDefs
    vulnfanatic.includeVariableDataflow
    vulnfanatic.dataflowMaxFunctions
    vulnfanatic.includeStackLayout
    vulnfanatic.scanIndirectCalls
    vulnfanatic.validationPass
    vulnfanatic.validatorModel
    vulnfanatic.validatorProvider
    vulnfanatic.validatorBaseUrl
    vulnfanatic.validatorApiKey
    vulnfanatic.minConfidence
    low
    medium
    high
    low
    vulnfanatic.flagUnparseableResponses
    UNKNOWN
    vulnfanatic.skipConstantArgCalls
    vulnfanatic.verdictReasoning
    concise
    full
    none
    concise
    vulnfanatic.runPhase1
    vulnfanatic.runPhase2
    vulnfanatic.runPhase3
    vulnfanatic.phase2RequireSymbols
    vulnfanatic.phase2ForceEnable
    vulnfanatic.tokenizerEncoding
    vulnfanatic.offlineBuildContext
    vulnfanatic.debugLogging
    vulnfanatic.debugAnonymous
    デバッグログ
    vulnfanatic.sendJsonResponseFormat
    vulnfanatic.tlsVerify
    vulnfanatic.caBundlePath
    CERTIFICATE_VERIFY_FAILED
    vulnfanatic.rulesPhase1Path
    vulnfanatic.rulesPhase2Path
    vulnfanatic.rulesPhase3Path