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

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
HintInject — Hint/Name Tableにシェルコードを埋め込むPoCプロジェクト | Kitploit
ツール/GitHubGitHub/frkngksl/hintinject
ペイロード生成エクスプロイトシェルコードペネトレーションテストバイナリ解析ペイロード開発
GitHubfrkngksl/hintinject

HintInject

Hint/Name Tableにシェルコードを埋め込むPoCプロジェクト

リポジトリを見る
114224ヶ月前Kitploit レビュー済み

人気

すべて見る →

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

すべてのツールを探索

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

すべてのツールを見る →
共有

HintInject

HintInject は、私が PE ファイルと Import Directory Table 構造をいじりながら開発したシェルコード埋め込み兼ローダーです。生のシェルコードファイルを受け取り、シェルコードをチャンクに分割して Hint/Name Table エントリ(ローダー実行ファイル上の偽のインポート DLL エントリの Import Lookup Table から到達可能)に配置します。その後、ローダーがこれらのチャンクをマージしてシェルコードを実行します。これが新しい手法かどうかはわかりませんが、面白いので共有したいと思います。

DLL ローディングプロセス

HintInject の仕組みを説明する前に、Stack Overflow の投稿を参考にしながら、DLL の読み込みプロセスについて簡単に触れておきます。

必要な DLL と関数/インポートに関する情報を取得するには、最初に Import Directory Table を確認する必要があります。Import Directory Table はエントリのテーブルで、インポートされる DLL ごとに 1 つのエントリがあります。これらのエントリは、インポートされる DLL 名へのポインタ、Import Lookup Table へのポインタ、Import Address Table へのポインタ、およびその他のさまざまな情報のためのフィールドを保持します。

簡単に言うと、Import Lookup Table はインポートに関する情報を指し示し、Import Address Table はインポートのアドレスを指し示します。ただし、実行ファイルがディスク上にある場合、または DLL ローディングプロセスの直前では、Import Address Table は Import Lookup Table と同一です。Import Address Table の内容は、DLL ローディングプロセス中にインポートのアドレスで上書きされます。

詳細には立ち入らずに、以下の図を見て、これら 3 つのテーブルの関係を確認できます。

もう少し詳しく見ると、Import Lookup Table はインポートの名前を直接保持しているわけではありません。名前でインポートされる関数の場合、Hint/Name Table エントリの RVA を保持します。これらのエントリは、関数名を NULL 終端の ASCII 文字列として格納します。したがって、Hint/Name Table エントリの構造体定義は次のようになります。

root@kitploit:~
typedef struct _IMAGE_IMPORT_BY_NAME {
    WORD    Hint;
    CHAR   Name[1];
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME; 

ここでの Hint フィールドは、実際には DLL のエクスポート名ポインタテーブルへのインデックスです。これは、そのインポートの位置を高速に見つけるために使用されます。したがって、Import Lookup Table と Hint/Name テーブルの関係は、以下の図でまとめられます。

まとめると、DLL とそのインポートを見つけるには、次の手順に従う必要があります。

  1. Optional Header の DataDirectory 配列から Import Directory Table に移動します。
  2. Import Directory Table のエントリを走査し、名前フィールドを確認して目的の DLL を見つけます。
  3. 正しいエントリを見つけたら、OriginalFirstThunk フィールドを使用してその Import Lookup Table に移動します。
  4. Import Lookup Table 内のすべてのエントリ(Hint/Name Table エントリへのポインタ)を走査します。
  5. Hint/Name Table エントリの Name フィールドからインポート名を確認します。

HintInject の仕組み

最近、x86matthew が共有した ImportDLLInjection テクニックを調べているときに、メモリに読み込まれた DLL の Import Directory に偽のエントリを追加する方法を学びました。その後、楽しみと知識のリフレッシュを兼ねて、ディスク上のバイナリのインポートテーブルに直接偽のエントリを追加する小さなプロジェクトを開発したいと思いました。このプロジェクトを開発するために DLL ローディングプロセスを再確認していると、このプロセスで使用される Hint/Name Table エントリの Hint フィールドが目に留まりました。

MSDN のドキュメントによると、このフィールドは Windows ローダーが、名前でインポートされた関数のアドレスを、その関数が含まれる DLL のエクスポート名テーブルから直接見つけるために使用されることがわかりました。ただし、同じドキュメントには、このフィールドを使用して関数が見つからなかった場合、その関数は DLL のエクスポート名テーブル内で二分探索によって検索されるとも記載されていました。この記述に基づき、このフィールドに不正な値を入れても DLL ローディングプロセスは中断されないと考えました。

上で述べたように、インポートされる関数ごとに Hint/Name テーブルへのエントリが 1 つあります。つまり、インポートごとに 2 バイトを使用できることになります。複数のインポートを組み合わせることで、悪意のあるシェルコードを格納するのに十分な Hint フィールドを確保できます。その結果、偽のインポート DLL エントリの Hint/Name エントリにシェルコードを埋め込んだローダーバイナリを作成できます。そのローダーバイナリは、実行時にシェルコードをマージするためにこれらのエントリにアクセスできます。

HintInject は、Hint/Name テーブルにシェルコードを保持するようなローダーを作成するために使用できます。まず、.rrdata という名前の新しいセクションを作成し、現在のインポートディレクトリをこのセクションにコピーします。その後、インポートが入力シェルコードを保持するために使用される新しい偽のエントリを追加します。セクションの残りのバイトは、新しい偽のエントリの Import Lookup Table、Import Address Table、DLL 名、および Hint/Name テーブルを格納するために使用されます。最終ステップとして、HintInject はインポートの Hint フィールドを使用して入力シェルコードのチャンクを配置します。

ローダーバイナリのインポートの例:

Screen Shot 2022-05-08 at 11 43 42

使い方

  1. Release オプションでプロジェクトをビルドします。
  2. HintInject.exe を、生の形式のシェルコードと出力パスを指定して実行し、シェルコードローダーを作成します: HintInject.exe <Shellcode File> <Output Name>
  3. ローダーを実行してシェルコードを直接実行するか、PID を指定してシェルコードを注入します: Loader.exe <PID>
  4. 必要に応じて、HintInjectLoader/Main.cpp ファイル内の InjectShellcode 関数を変更することで、シェルコードの注入方法を変更できます。

Windows 10 19044 および Visual Studio 2019 でテスト済み:

制限事項

  1. シェルコードを実行するローダー上の偽の DLL エントリに関しては、DLL 名とインポートされる関数名の両方が実際に存在している必要があります。そうでない場合、ローダー実行ファイルの起動時に Missing DLL エラーが発生します。そのため、プロジェクトでは System32 にあるいくつかの正当な DLL を使用しました。
  2. シェルコードのサイズが大きく、シェルコード用のローダーを作成できない場合は、DllNamesForFakeImports.h ファイルの dllNames 配列に他の DLL を追加できます。
  3. 作成されるローダーごとに、インポートされる関数はランダムに選択されます。ただし、偽のエントリを作成するために使用される DLL の順序を変更したい場合は、DllNamesForFakeImports.h ファイルの dllNames 配列も編集する必要があります。デフォルトでは、HintInject は配列の順序に従って DLL から関数を選択します。つまり、ツールは最初に user32.dll からエクスポートされた関数を選択し、シェルコードのサイズが 2 * user32.dll のエクスポート数 より大きい場合は、advapi32.dll などのエクスポートも使用し始めます。
root@kitploit:~
static LPCSTR dllNames[] = {"user32.dll","advapi32.dll","gdi32.dll","wininet.dll","comctl32.dll","shell32.dll","wsock32.dll","oleaut32.dll","ws2_32.dll","urlmon.dll"};

参考文献

  • https://stackoverflow.com/questions/32841368/whats-the-difference-between-the-import-table-import-adress-table-and-import
  • https://0xrick.github.io/win-internals/pe6/
  • https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#hintname-table
  • https://www.x86matthew.com/view_post?id=import_dll_injection

免責事項

許可されたセキュリティテストにのみ使用してください。明示的な許可なくシステムに対してこのツールを悪用することは違法です。

ツールをダウンロード