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

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
MemITM — メモリ内で中間者攻撃を行うツール | Kitploit
ツール/GitHubGitHub/amossys/memitm
動的分析 (サンドボックス)メモリフォレンジックエクスプロイトリバースエンジニアリングデバッガファジングバイナリ解析
GitHubamossys/memitm

MemITM

メモリ内で中間者攻撃を行うツール

リポジトリを見る
126277年前Kitploit レビュー済み

人気

すべて見る →

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

すべてのツールを探索

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

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

MemITMツールとは?

MemITM(Mem In The Middle)ツールは、Windowsプロセスメモリ内の「メッセージ」を簡単にインターセプトするために開発されました。暗号化前のネットワークメッセージやIPCメッセージをキャプチャし、それらを検査したり、ファジングのために変更したりするために、多くのカスタムメモリインターセプションツールを開発してきました。各ツールは非常にカスタムで汎用性がなく、C/ASMで実装されており、使用・保守・適応が容易ではありませんでした。

MemITMツールはこれらの問題に対処するために開発され、以下で構成されています:

  • IDA Pythonスクリプト:インターセプションポイントをどこにどのように配置するか(相対アドレス、バッファとそのサイズの見つけ方、フックの配置方法など)を示す「config」ファイルを生成します。
  • DLLファイル:ターゲットプロセスに注入され、configをロードしてフックを配置します。
  • DLLファイルインジェクター:DLLをターゲットプロセスにロードします。
  • Pythonスクリプト:注入されたDLL/フックと通信し、インターセプトされたバッファをリアルタイムで取得し(変更も可能)、自由に修正できる非常にシンプルなコールバックで動作します。

こちらからダウンロードできます(ソース+コンパイル済み):https://github.com/Amossys/MemITM

MemITMの簡単さは? (例1: WriteFile)

特定のWindowsプロセスにおけるファイル書き込みをインターセプトしたいとします(実現するにはもっと簡単な方法がありますが、例として)。ファイル書き込みは kernelbase.dll によってエクスポートされる WriteFile 関数によって行われ、BOOL WriteFile( HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, ...) というスキームに従います。WriteFileは __fastcall 関数です:lpBuffer は RDX、NumberOfBytesToWrite は R8 で指されます。これらのバッファをインターセプトしましょう。

  1. IDA Proで "kernelbase.dll" ファイルを開き、generate.idapython.py スクリプトをロードし、getHook(LocByName("WriteFile"), "rdx","r8") を実行し、続けて updateConfig("config.bin") を実行します。

  2. notepadを実行し、次に python memitm.py notepad.exe config.bin を実行します。

これだけです! WriteFile 関数にフックが配置され、memitm.py の "logger" と "fuzzer" 関数がバッファのコピーを受け取ります。

バッファがレジスタで指されていません! (例2: NtCreateFile)

getHook 関数ではバッファとそのサイズのレジスタを指定できますが、そうでない場合もあります。NtCreateFile システムコールをインターセプトしてファイル名を取得したいとします。NtCreateFile は NTSTATUS NtCreateFile( OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, ...) というスキームに従い、ファイル名は ObjectAttributes->ObjectName->Buffer で取得できます(サイズは ObjectAttributes->ObjectName->Length * sizeof(WCHAR))。

getHook では、レジスタの代わりに t1customOpcodes パラメータでシェルコードを指定することもできます。このシェルコードは:

  • バッファポインタを RCX レジスタに配置する。
  • バッファのサイズを RDX レジスタに配置する。
  • スタックを壊さない。

NtCreateFile の場合、このASMコードを実行して処理できます:

root@kitploit:~
mov rax, [r8+0x10]    ; rax は ObjectAttributes->ObjectName になる
mov rcx, [rax + 0x10] ; rcx は ObjectAttributes->ObjectName->Buffer になる
mov rdx, [rax]        ; rdx は ObjectAttributes->ObjectName->Length になる
and rdx, 0xFFFF       ; Length は USHORT
shl rdx, 1            ; そして *2 しなければならない

これをアセンブルします(例えばオンラインの逆アセンブリサイトを使用):498B4010488B4810488B104881E2FFFF000048D1E2。getHook の呼び出しは次のようになります:getHook(LocByName("NtCreateFile", t1customOpcodes="498B…E2")。

複数の呼び出しをインターセプトできますか?

はい!configファイルには複数のインターセプションポイント定義を埋め込むことができ、getHook 関数はファイルに追加します。複数のモジュールにインターセプションポイントを設定できます。例えば、ALPCメッセージとIOCTLメッセージを同時にインターセプトできます。

Pythonコールバック内で「メッセージID」によってそれらを区別できます。

おっと、BSOD/システムフリーズ!

心配しないでください。簡単なHTTPサーバー(logserver.py)と httpNetSend 関数もあり、テストケース(および変更)をリアルタイムでリモートホストに送信できます。

どのようにファジングしますか?

そうですね、bufferBitFlip 関数を使ってビットを反転させることができます。生のメッセージをログに記録することで、独自のディセクタを作成し、手動でより良いファザーを実装し始めることができます。覚えておいてください:バッファサイズは変更できません!

例えば、WriteFile の例では、次の fuzzer 関数が "hello" を "world" に置き換えます:

root@kitploit:~
def fuzzer(data, msgID=None, pid = 0):
   return data.replace("hello","world")

例3: ALPCメッセージの解析

例えば、ALPCメッセージの場合、以下のような memitm.py のセットアップが考えられます:

root@kitploit:~
def logger(data, msgID=None, pid=0):
    totalLen = 0
    dataLen = 0
    typ = 0
    dataInfoOffset = 0
    cid = 0
    tid = 0
    messageID = 0
    clientViewSize = 0
    # skip the PORT_MESSAGE header (0x18 bytes)
    if len(data) > 0x18:
        totalLen = struct.unpack("<H",data[:2])[0]
        dataLen = struct.unpack("<H",data[2:4])[0]
        typ = struct.unpack("<H",data[4:6])[0]
        dataInfoOffset = struct.unpack("<H",data[6:8])[0]
        zeroInit = struct.unpack("<L",data[4:8])[0]
        cid = struct.unpack("<L",data[8:0xC])[0]
        tid = struct.unpack("<L",data[0xC:0x10])[0]
        messageID = struct.unpack("<L",data[0x10:0x14])[0]
        clientViewSize = struct.unpack("<L",data[0x14:0x18])[0]
    logMessage = "ALPC message : %x:%x - %x:%x - %d:%d - %x - %x" % (totalLen, dataLen, typ, dataInfoOffset, cid, tid, messageID, clientViewSize)
    print logMessage
    return

内部動作の仕組み

IDA Proスクリプトにはシンプルな「フッキング」エンジンが組み込まれており、いくつかの命令を特定の領域に移動できます(DIMCT ツールから派生)。メモリ相対命令や相互参照など、多くのコーナーケースを処理する必要があり、複数の相互参照を含む本当に小さな基本ブロック(x86バイナリで5バイト未満、x64で12バイト未満)をインターセプトしようとすると、「ここにフックをインストールできません」というメッセージが多数表示される可能性があります。詳細はソースコードをお読みください。

configファイルに次の情報を生成します:

  • モジュール名
  • インターセプションポイントの相対アドレス
  • バッファ/長さを RCX/RDX に配置し、DLLのログルーチンを呼び出すインターセプションフック領域(別名 "T1 トランポリン")
  • コンテキストを復元し、置き換えられた命令を実行してからインターセプションポイントに戻る復元フック領域(別名 "T2 トランポリン")
  • 絶対アドレスに変換されパッチが必要な相対命令のための復元フック領域の再配置

DLLインジェクターはシンプルなDLLインジェクターです(CreateRemoteThread/LoadLibraryA の仕組み)。

DLL自体は共有メモリ領域を初期化し、configデータを待ちます(共有メモリ領域には3つの汎用フィールドがあります:共有メモリメッセージID、メッセージサイズ、メッセージバッファ)。受信後、configを解析してメモリにフックをインストールし、その後はconfigの更新は許可されません(新しいフックを設定するにはプロセスを強制終了する必要があります)。配置されたフックはすべて genericHookFunction DLL関数に着地します。この関数は、バッファデータ、そのサイズ、およびメッセージID(共有メモリメッセージIDフィールドの上位ビットに設定)でメモリ領域(クリティカルセクションで保護)を埋めるだけです。Pythonプロセスに通知するために、2つのイベントが使用され、新しいメッセージのシグナリングと、プロセスがそれらをパッチするのを待機します(タイムアウトは2秒)。バッファが更新された場合、元のバッファも変更されます。

memitm.py スクリプトはインジェクタープロセスを実行し、共有メモリが作成されるのを待ちます。その後、設定を送信し、メッセージイベントを待ちます。受信されると、共有メモリが読み取られ、logger および fuzzer 関数がバッファ、プロセスID、メッセージIDとともに呼び出されます。logger 関数が元のバッファとは異なるバッファを返し、そのサイズが等しい場合、共有メモリ領域に書き込まれます。その後 "ACK" イベントがシグナリングされ、スクリプトは新しいメッセージを待ちます。

これで終わりです!

このツールがお役に立てば幸いです。コントリビューションやレビューを歓迎します!また、もしフランス人でレンヌが好きなら、採用しています :)

ツールをダウンロード