

RefleXXionは、AV/EPP/EDRなどで利用されるユーザーモードフックをバイパスするためのユーティリティです。ユーザーモードフックをバイパスするために、まずLdrpThunkSignature配列内のNtOpenFile、NtCreateSection、NtOpenSection、NtMapViewOfSectionのシステムコール番号を収集します。その後、ユーザーモードフックをバイパスするために2つのテクニックから選択できます。
テクニック1:C:\Windows\System32\ntdll.dllからNTDLLをファイルとして読み込みます。パース後、メモリ上に既にロードされているNTDLL(フックが実行されている場所)の.TEXTセクションを、クリーンなNTDLLの.TEXTセクションで置き換えます。
テクニック2:NTDLLをKnownDllsからセクションとして読み込みます(\KnownDlls\ntdll.dll)。DLLファイルはKnownDllsにセクションとしてキャッシュされているためです。パース後、メモリ上に既にロードされているNTDLL(フックが実行されている場所)の.TEXTセクションを、クリーンなNTDLLの.TEXTセクションで置き換えます。
方法論とすべてのテクニックの詳細なフローを以下に示します。

Visual Studioでプロジェクトを開いてコンパイルできます。プロジェクト全体はx64アーキテクチャをサポートしており、DebugモードとReleaseモードの両方に対応しています。
RefleXXion-EXEソリューションはPoC目的のEXEを生成します。プロジェクトの動作を段階的に理解したい場合に役立ちます。main関数にはTechnique1とTechnique2の関数定義が含まれています。いずれかをコメントアウトしてコンパイルしてください。両方の関数を同時に使用しないでください。
RefleXXion-DLLソリューションは、NTDLLのユーザーモードフックをバイパスしたいプロセスに注入するDLLを生成します。main.cppファイルの先頭に、使用するテクニックの定義があります。その中から一つを選んでコンパイルできます。すべての値を同時に設定せず、希望するテクニックのみを設定してください。設定例を以下に示します。
// Techniques configuration section
#define FROM_DISK 1 // If you set it to 1, the Technique-1 will be used. For more information; https://github.com/hlldz/RefleXXion
#define FROM_KNOWNDLLS 0 // If you set it to 1, the Technique-2 will be used. For more information; https://github.com/hlldz/RefleXXion
RefleXXionは現在、x64アーキテクチャのみをサポートしています。
RefleXXionはNTDLLの関数のみアンフックします。他のDLL(kernel32.dll、advapi32.dllなど)もアンフックする必要があるかもしれません。その場合は、プロジェクト内の必要な箇所を簡単に編集できます。
RefleXXionは、.TEXTセクションの上書きプロセスを開始する際にのみRWXメモリ領域を使用します。このプロセスでは新しいメモリ領域は作成されず、既存のメモリ領域(既にロードされているNTDLLのTEXTセクション)がRWXに変更され、その後RXに戻されます。
ULONG oldProtection;
ntStatus = NtProtectVirtualMemory(NtCurrentProcess(), &lpBaseAddress, &uSize, PAGE_EXECUTE_READWRITE, &oldProtection);
memcpy()...
ntStatus = NtProtectVirtualMemory(NtCurrentProcess(), &lpBaseAddress, &uSize, oldProtection, &oldProtection);
追記:RefleXXionは、クリーンにインストールされたNTDLL上でNtProtectVirtualMemory APIを呼び出します。その際、CustomGetProcAddress関数を使用します。なぜなら、クリーンなNTDLLはメモリにロードされていてもInLoadOrderModuleListに含まれていないため、ここ(https://stackoverflow.com/questions/6734095/how-to-get-module-handle-from-func-ptr-in-win32)のような解決策は機能しません。そのため、カスタムのGetProcAddress関数が存在し、使用されています。
RefleXXion DLLをディスクからターゲットプロセスにロードできます。Red Teamオペレーションのようなセンシティブな作業ではこのような実行方法は好ましくないかもしれません。そのため、sRDIプロジェクトを使用してRefleXXion DLLをシェルコードに変換するか、RefleXXionのコードを独自のローダーやプロジェクトに統合することができます。
注入されたプロセスにNTDLL(ファイルとして、またはセクションとして)を再ロードしても、ロードされたままにはなりません。RefleXXionは自身のプロセスのために開かれたすべてのハンドル(ファイルハンドルとセクションハンドル)を閉じます。