
Implementaciones en C# de técnicas de inyección de shellcode que incluyen inyección clásica, secuestro de hilos, vaciado de procesos y bombardeo de átomos, utilizando payloads de Meterpreter cifrados con AES para investigación de evasión de AV.
Una colección de técnicas de inyección de shellcode en C#. Todas las técnicas utilizan un payload de meterpreter cifrado con AES.
Iré ampliando este proyecto a medida que aprenda, descubra o desarrolle más técnicas.
Nota: El proyecto no está pensado para ser usado tal cual. Si va a utilizar alguna de las técnicas, tendrá más posibilidades de evadir el AV si crea un proyecto más pequeño y personalizado con la técnica elegida.
Si utiliza alguno de los códigos de estos repositorios, ¡manténgalo dentro de la legalidad!
Puede usar una técnica de inyección de ensamblado en PowerShell si desea evitar escribir binarios .Net en el disco.
ShellcodeRunner.cs : Esta técnica no es estrictamente una técnica de inyección (porque ejecutamos el shellcode en el mismo proceso) pero es la más simple de todas. Nos aseguramos de que el shellcode use una ubicación de memoria fija en un contexto unsafe. Cambiamos la protección de la página donde se encuentra el shellcode para poder ejecutarlo. Luego usamos una función delegada de C# para ejecutar el shellcode.
[+] Using technique: ShellcodeInjectionTechniques.ShellcodeRunner
[+] VirtualProtect() - set to PAGE_EXECUTE_READWRITE, shellcode address: 0x20D000418E0
[+] Executing shellcode - memory address: 0x20D000418E0
ClassicInjection.cs : Esta técnica asigna memoria en el proceso objetivo, inyecta el shellcode e inicia un nuevo hilo.
[+] Found process: 24484
[+] Using technique: ShellcodeInjectionTechniques.ClassicInjection
[+] VirtualAllocEx(), assigned: 0x23642220000
[+] WriteProcessMemory() - remote address: 0x23642220000
[+] CreateRemoteThread() - thread handle: 0x380
ThreadHijack.cs : Esta técnica secuestra un hilo inyectando código en el proceso objetivo, suspende el hilo secuestrado, establece el puntero de instrucción (RIP) en nuestro código inyectado y luego reanuda el hilo.
[+] 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 : Esta técnica crea un nuevo hilo local en estado suspendido, luego secuestramos el hilo, establecemos el puntero de instrucción (RIP) en nuestro código inyectado y reanudamos el hilo.
[+] 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 : Esta técnica es similar a la técnica de Secuestro de Hilo. Inyectamos el shellcode en un hilo remoto, luego encolamos un objeto APC en el hilo. Cuando el hilo entra en un estado alertable (cuando llama a SleepEx, SignalObjectAndWait, MsgWaitForMultipleObjectsEx, WaitForMultipleObjectsEx, o WaitForSingleObjectEx) ejecuta nuestro shellcode apuntado por nuestro objeto APC encolado.
[+] 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 : Esta técnica inicia otro proceso en estado suspendido (svchost.exe), encuentra el punto de entrada del hilo principal, inyecta nuestro shellcode en él y luego reanuda el hilo.
[+] 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 : Esta técnica crea una nueva sección en memoria, crea una vista asignada local de la sección, copia nuestro shellcode en la vista asignada local y crea una vista asignada remota de la vista asignada local en el proceso objetivo. Finalmente, creamos un nuevo hilo en el proceso objetivo con la vista asignada como punto de entrada.
[+] 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 : Esta técnica es interesante en cómo escribimos shellcode en el proceso objetivo. Usamos la Tabla de Átomos Global que nos permite escribir cadenas terminadas en nulo con un tamaño máximo de 255 bytes. Encontramos una cueva de código para escribir nuestro shellcode, luego usamos llamadas APC para hacer que el proceso objetivo lea los Nombres de Átomos en memoria. Finalmente, usamos un par de llamadas APC para cambiar la protección de memoria del objetivo y ejecutar el shellcode.
Mi código difiere de la técnica original Atom Bombing, escrita en C/C++. Primero, encadeno Nombres de Átomos, usando múltiples APC, para formar un shellcode de más de 255 bytes. No uso cadenas ROP para forzar al proceso objetivo a llamar a VirtualProtect y luego ejecutar el código, uso la cola APC.
Este código requiere que el hilo principal entre en un estado alertable para ejecutar la cola APC y no limpio después de la ejecución del shellcode, el proceso objetivo se vuelve inestable. Planeo mejorar esta técnica (buscando hilos alertables y limpiando después), pero como PoC funciona bien.
[+] 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
La técnica de Bombardeo de Átomos coloca cadenas terminadas en nulo en la Tabla de Átomos Global, esto significa que debe usar shellcode que no tenga caracteres 0x00.
Recuerde que necesitará iniciar un proceso para inyectar, excepto cuando use el ejecutor de shellcode, la técnica de secuestro de hilo local o la técnica de vaciado de proceso (esta técnica inicia un nuevo proceso en estado suspendido).
[!] Unable to find process to inject into!
Cuando use el ejecutor de shellcode, la técnica de secuestro de hilo local o la técnica de vaciado de proceso, deberá comentar el código en Program.cs que busca el proceso para inyectar:
/*
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];
*/