
Реализации на C# методов внедрения шеллкода, включая классическое внедрение, перехват потока, опустошение процесса и атомную бомбардировку, с использованием зашифрованных с помощью AES полезных нагрузок Meterpreter для исследования обхода антивирусов.
Коллекция техник внедрения шеллкода на C#. Все техники используют полезную нагрузку Meterpreter, зашифрованную AES.
Я буду дополнять этот проект по мере изучения, обнаружения или разработки новых техник.
Примечание: Проект не предназначен для использования как есть. Если вы собираетесь использовать какую-либо из техник, шансов обойти антивирус будет больше, если вы создадите меньший, индивидуализированный проект с выбранной техникой.
Если вы используете какой-либо код из этих репозиториев, соблюдайте закон!
Вы можете использовать технику внедрения сборки через PowerShell, если хотите избежать записи .Net-бинарных файлов на диск.
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
APCInjection.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 байт. Мы находим кодовую пещеру для записи нашего шеллкода, затем с помощью вызовов APC заставляем целевой процесс считывать имена атомов в память. Наконец, с помощью пары вызовов APC меняем защиту памяти цели и выполняем шеллкод.
Мой код отличается от оригинальной техники Atom Bombing, написанной на C/C++. Во-первых, я объединяю имена атомов в цепочку, используя несколько 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 помещает строки, завершающиеся нулевым символом, в глобальную таблицу атомов, поэтому необходимо использовать шеллкод, не содержащий символов 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];
*/