
Una tecnica avanzata di evasione in memoria che fa oscillare la protezione della memoria dello shellcode tra RW/NoAccess e RX e poi ne crittografa/decrittografa i contenuti.
Una implementazione PoC per un'altra tecnica di evasione in-memory che cifra e decifra ciclicamente il contenuto dello shellcode per farlo fluttuare tra protezioni di memoria RW (o NoAccess) e RX.
Quando il nostro shellcode risiede in pagine di memoria RW o NoAccess, scanner come Moneta o pe-sieve non saranno in grado di individuarlo e dumpare per ulteriori analisi.
Dopo aver rilasciato ThreadStackSpoofer ho ricevuto alcune domande su questo punto del README:
Cambia la protezione delle pagine di memoria del tuo Beacon in RW (da RX/RWX) e cifra il loro contenuto prima di andare in sleep (questo potrebbe eludere scanner come Moneta o pe-sieve)
In precedenza ero abbastanza sicuro che la community sapesse già come cifrare/decifrare i propri payload e cambiare le protezioni di memoria per eludere gli scanner di memoria che cercano regioni eseguibili anomale. Le domande hanno dimostrato il contrario, così ho deciso di rilasciare questo PoC non weaponizzato per documentare un'altra strategia di evasione e offrire un'implementazione di esempio con cui la community possa lavorare.
Questo PoC è una dimostrazione di una tecnica piuttosto semplice, già nota alla community offensiva (quindi non sto portando nulla di davvero nuovo qui), nella speranza di svelare il segreto dietro la magia mostrata da alcuni framework commerciali che dimostrano le loro capacità di evasione mirate a entrambi gli scanner di memoria sopra citati.
Ecco un confronto quando si fluttua a RW (un'altra opzione è fluttuare a PAGE_NOACCESS - descritta sotto):

Questa implementazione insieme al mio ThreadStackSpoofer offre alla community di Offensive Security implementazioni di esempio per recuperare terreno rispetto all'offerta dei prodotti C2 commerciali, così da non fare peggio nei nostri tooling Red Team. 💪
Questo programma esegue un self-injection di shellcode (approssimativamente tramite il classico VirtualAlloc + memcpy + CreateThread).
Quando lo shellcode viene eseguito (questa implementazione mira specificamente agli impianti Cobalt Strike Beacon) una funzione di Windows viene hookkata per intercettare il momento in cui Beacon va in sleep kernel32!Sleep.
Ogni volta che la funzione hookkata MySleep viene invocata, localizza i confini della propria allocazione di memoria, ne cambia la protezione in RW e applica xor32 a tutti i byte ivi memorizzati.
Dopo aver atteso il tempo previsto, quando lo shellcode torna al nostro handler MySleep, decifriamo i dati dello shellcode e ripristiniamo la protezione a RX.
PAGE_READWRITE funziona cosìkernel32!Sleep facendolo puntare al nostro callback.VirtualAlloc + memcpy + CreateThread. Contrariamente a quanto avevamo in ThreadStackSpoofer, qui non hookkiamo nulla in ntdll per avviare il nostro shellcode, ma saltiamo ad esso dalla nostra stessa funzione. Questo tenta di evitare di lasciare in memoria semplici IOC che puntano a memoria ntdll modificata.MySleep viene invocato.RWkernel32!Sleep originale per evitare di lasciare in memoria un semplice IOC che segnali che Sleep sia stato trampolinato (hook inline).::Sleep originale per lasciare Beacon in sleep in attesa di ulteriori comunicazioni.RX e poi ri-hookkiamo kernel32!Sleep per garantire l'intercettazione dei successivi sleep.PAGE_NOACCESS funziona cosìkernel32!Sleep facendolo puntare al nostro callback.VirtualAlloc + memcpy + CreateThread ...MySleep viene invocato.PAGE_NOACCESSkernel32!Sleep originale per evitare di lasciare in memoria un semplice IOC che segnali che Sleep sia stato trampolinato (hook inline).::Sleep originale per lasciare Beacon in sleep in attesa di ulteriori comunicazioni.kernel32!Sleep per garantire l'intercettazione dei successivi sleep.RX e l'esecuzione dello shellcode riprende.La tecnica non è nuova di zecca, non è qualcosa che ho ideato io. È semplicemente un'implementazione che mostra il concetto e il suo utilizzo pratico per permettere alla nostra community di Offensive Security di recuperare terreno rispetto all'offerta dei framework C2 commerciali.
In realtà, sono stato introdotto all'idea di cambiare la protezione di memoria dello shellcode un paio di anni fa grazie al lavoro di Josh Lospinoso nel suo fantastico Gargoyle.
Ecco ulteriori riferimenti:
Gargoyle porta il concetto di shellcode auto-consapevole e auto-fluctuante molto più avanti, sfruttando una sequenza ROP che chiama VirtualProtect.
Tuttavia la tecnica è impressionante, ma è altrettanto difficile da sfruttare con il Beacon di Cobalt Strike senza dover terminare il suo thread e mantenere la re-inizializzazione del Beacon in memoria.
Non è affatto perfetto, tuttavia, poiché operiamo già dalla base del nostro processo loader di self-injection, possiamo fare quello che vogliamo con l'ambiente in cui opera lo shellcode e nasconderlo come preferiamo. Questa tecnica (e la precedente, cioè ThreadStackSpoofer) mostra i vantaggi dell'eseguire i nostri shellcode in questo modo.
L'implementazione della fluttuazione a PAGE_NOACCESS è ispirata al lavoro di ORCA666 presentato nel suo https://github.com/ORCA666/0x41 injector.
Ha dimostrato che:
Questa implementazione contiene questa idea, disponibile con l'opzione 2 in <fluctuate>.
Date un'occhiata anche agli altri suoi progetti.