
逆コンパイルされたバイナリの脆弱性を特定するためのBianryNinjaプラグインで、プログラムによるスキャンとLLMサポートの両方を備えています。
LLM支援の脆弱性調査のための Binary Ninja プラグインです。
VulnFanatic-NG はサイドバーパネルを追加し、現在のバイナリをスキャンして、疑わしいコードが実際に脆弱かどうかを LLM(デフォルトではローカルホストの OpenAI 互換モデル、または Anthropic Claude、Google Gemini、Azure OpenAI(LLM バックエンドを参照))に判断させます。主に Binary Ninja の**逆コンパイラ出力(HLIL)**を使用し、必要に応じてアセンブリにフォールバックして、確認された問題のみをコードへのクリック可能な参照付きで報告します。
スキャンは最大3つのフェーズで実行されます(フェーズ3はオプトインかつオンラインのみ)。
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)に収めます。
__*_chk や境界チェック付き *_s バリアントは先頭に追加の引数が付くため、フォーマット/サイズ/宛先の位置がずれます。s->buf のような構造体フィールドは s のポインタサイズではなく、そのフィールドの実際の配列サイズに解決されます。型セクションの構造体定義にもフィールドごとのバイトサイズが含まれます。0x40 であることが証明されたり、[0, 0xff] に制限される)。モデルはサイズをバッファ容量と比較する際に推測ではなくこれを真実として使用します。vulnfanatic.includeStackLayout)。if/ループ/switch 条件)。MAIN→ABCD→strcpy の場合、MAIN と ABCD が他で呼び出す関数も含む)。危険な値を制御する境界/検証チェックが含まれている可能性があるためです(vulnfanatic.includeCallPathSiblings。予算が許す限り追加されます)。recv/read/getenv などの入力関数)。このコンテキストとルール固有のプロンプトがモデルに送信され、モデルは構造化された判定を返します。問題ではないものは破棄されます。プロンプトは強力なローカルコードモデル(例: 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 は精度を失います(思考連鎖がまったくないため)。常に有効な精度サポート機能(検出名を抑制せずにモデルに情報を提供します):
_s(Annex K)と _chk(FORTIFY)バリアント、および長さ制限付き API を、サイズ引数自体が誤っていない限り安全として扱います。Scan Offline ボタンは、モデルなしでフェーズ1を実行します — phase1_rules.json の各ルールの offline ブロックで宣言された純粋にプログラム的なヒューリスティックです。危険な呼び出し箇所にフラグを立て、明らかに安全なものは除外し、ヒューリスティックな信頼度を割り当てます。
memcpy/memmove、定数文字列からの strcpy、定数フォーマットの printf、定数コマンドの system など — 支配的な引数がコンパイル時定数であり、攻撃者によって制御され得ない呼び出しです。「定数」には、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 で無効にします。
バイナリに実際のシンボル / 変数名があると思われる場合にのみ実行されます。rules/phase2_rules.json で定義されたセキュリティ関連関数を特定します — 認証、暗号化(弱いアルゴリズムを含む)、署名/証明書検証、セッション/トークン処理、アクセス制御、秘密/キー処理、入力検証、非定数時間の秘密比較、安全でないデシリアライゼーション — 関数名と参照される文字列で照合し、モデルが監査します。
ファームウェア堅牢化の監査で、フォールトインジェクション(電圧/クロック/EMグリッチング)およびサイドチャネル(タイミング/電力)攻撃に対するもので、ハードウェア攻撃の緩和ガイダンスに基づいています。バグを見つけるフェーズ1〜2とは異なり、フェーズ3はセキュリティ上重要な関数における欠落または違反した堅牢化コントロールを報告します — 例: デフォルトフェイル分岐、二重チェックされたセキュリティ判断、ループ後のカウンタ検証、高ハミング距離の状態定数(単純な 0/1 ではなく)、定数時間の全長シークレット比較、ランダムオフセットでのシークレットアクセス/消去、暗号化してから検証(anti-DFA)、制御フロー整合性カウンタ、ユーザーランド暗号の回避、生の鍵素材を直接扱わないこと(rules/phase3_rules.json)。
コンパイラの最適化によってソースレベルの保護が削られる可能性があるため、これらのコントロールはコンパイル済みバイナリで検証するのが最適です — まさにこれがチェックするものです。フェーズ3はLLMのみ(オンライン)、シンボルゲート、デフォルトでは無効です。New Scan タブの Phase 3 チェックボックスでスキャンごとに有効にします(オフラインモードでは実行されません)。
検出名はテーブル(ステータス、信頼度、フェーズ、CWE、関数、アドレス、タイトル)に一覧表示され、詳細ペインには説明、分析スクラッチパッド、検証ノートが表示されます。行をダブルクリックすると、バイナリビューがコードに移動します。