
ブルートフォースで取得した XFG ハッシュを使用して正確な関数プロトタイプを復元する Binary Ninja プラグイン
このリポジトリには、eXtended Flow Guard(XFG)ハッシュを生成および検索するためのスクリプトが含まれています。
この仕組みの詳細な解説は、International Journal Of Proof Of Concept || GTFO の22号に掲載されています。
このPoCに対する私の作業は、Microsoftのコンパイラの関連部分を広範囲にわたってリバースエンジニアリングしたQuarkslabの人々によって大幅に簡素化されました。XFGハッシュがどのように計算されるかに関する彼らの詳細な解説は、こちらで読めます: https://blog.quarkslab.com/how-the-msvc-compiler-generates-xfg-function-prototype-hashes.html
注: これは決してXFGをエクスプロイト緩和策として「破る」ものではなく、シンボルのない関数を明らかにするためにその副作用を利用しているだけです。
要するに、Windowsに実装されているXFGは、間接関数呼び出しの可能なターゲットを、有効な関数エントリポイントだけでなくシグネチャが一致する関数に限定することで、Control Flow Guard(CFG)のエクスプロイト緩和を拡張し、より厳格にしています。 そのために、各関数に対してXFGハッシュが計算され、実行時にそれに対するチェックが行われます。ハッシュは関数プロトタイプ(つまり、呼び出し規約、引数とその型)のみに基づいています。そのため、既知の型に対してハッシュを事前計算し、後で未知のバイナリの関数について検索することができます。
検索が成功した場合、すべての引数の正確な数と型、および関数の戻り値を100%確信することができます。これは、公開シンボルのないバイナリや関数にとって非常に有用です。
PoC||GTFOの完全な記事を、お近くのミラーから読むことをお勧めします。
スクリプトは以下のとおりです:
これらのスクリプトを使用するには、まずgen_function_prototypes.pyを変更して、調査対象に固有の「プリミティブ型」、構造体、列挙型を追加します。また、総当たりする引数の最大数も選択する必要があります。3つまでなら1分、4つまでなら1日かかります...
すべての組み合わせの関数プロトタイプが生成されたら、gen_hash_from_ast.pyを実行します。このスクリプトは、先ほど生成したファイルを行ごとに解析し、対応するXFGハッシュを生成します。
それが完了すると、対応するXFGハッシュを持つ関数プロトタイプのSQLiteデータベースが得られます。非常にシンプルなBinary Ninjaプラグインがxfg_analyzer.pyに含まれています。XFGで保護されたバイナリに対して実行すると、すべてのXFGハッシュを見つけ、データベースで検索し、一致するものがあれば、定義された関数に新しい関数プロトタイプを適用します。
これはあくまでPoCであることに注意してください。本当に有用にするには、巨大なハッシュデータベース(できればWindowsのヘッダーファイルにあるすべての構造体・列挙型名でシードされたもの)を生成し、オンライン検索ができるようにする必要があります。さらに、このアイデアをC++のXFGハッシュに拡張するのは非常に面白いプロジェクトになるでしょう。
このリポジトリのコードはどのような形であれ自由にご利用ください。役に立った場合は、ぜひご連絡ください。