
Eine fortschrittliche In-Memory-Evasion-Technik, die den Speicherschutz von Shellcode zwischen RW/NoAccess und RX umschaltet und anschließend dessen Inhalt ver- und entschlüsselt.
A PoC implementation for an another in-memory evasion technique that cyclically encrypts and decrypts shellcode's contents to then make it fluctuate between RW (or NoAccess) and RX memory protection.
When our shellcode resides in RW or NoAccess memory pages, scanners such as Moneta or pe-sieve will be unable to track it down and dump it for further analysis.
Nach der Veröffentlichung von ThreadStackSpoofer habe ich einige Fragen zu folgendem Punkt der README erhalten:
Ändere den Schutz der Speicherseiten deines Beacons auf RW (von RX/RWX) und verschlüssele deren Inhalte vor dem Schlafen (das könnte Scanner wie Moneta oder pe-sieve umgehen)
Zuvor war ich ziemlich sicher, dass die Community bereits weiß, wie sie ihre Payloads verschlüsseln/entschlüsseln und ihre Speicherschutzberechtigungen umstellen kann, um Speicherscanner zu umgehen, die nach anomalen ausführbaren Regionen suchen. Die Fragen haben das Gegenteil bewiesen, also habe ich beschlossen, diesen nicht bewaffneten PoC zu veröffentlichen, um eine weitere Evasion-Strategie zu dokumentieren und der Community eine Beispielimplementierung zur Arbeit anzubieten.
Dieser PoC ist eine Demonstration einer relativ einfachen Technik, die der Offensive-Community bereits bekannt ist (ich bringe hier also wirklich nichts Neues), in der Hoffnung, die Geheimnisse hinter der Magie zu enthüllen, die einige kommerzielle Frameworks zeigen, die ihre Evasion-Fähigkeiten gegen beide zuvor genannten Speicherscanner demonstrieren.
Hier ist ein Vergleich beim Fluktuieren zu RW (eine andere Option ist das Fluktuieren zu PAGE_NOACCESS - unten beschrieben):

Diese Implementierung zusammen mit meinem ThreadStackSpoofer bringt der Offensive-Security-Community Beispielimplementierungen, um mit dem Angebot kommerzieller C2-Produkte gleichzuziehen, damit wir in unseren Red-Team-Tools nicht schlechter abschneiden. 💪
Dieses Programm führt eine Selbstinjektion von Shellcode durch (grob über klassisches VirtualAlloc + memcpy + CreateThread).
Wenn der Shellcode läuft (diese Implementierung zielt speziell auf Cobalt-Strike-Beacon-Implantate ab), wird eine Windows-Funktion gehookt, die den Moment abfängt, in dem Beacon einschläft: kernel32!Sleep.
Immer wenn die gehookte MySleep-Funktion aufgerufen wird, lokalisiert sie die Grenzen ihrer Speicherzuordnung, stellt deren Schutz auf RW um und wendet xor32 auf alle dort gespeicherten Bytes an.
Nachdem die erwartete Zeit abgewartet wurde, entschlüsseln wir, wenn der Shellcode zu unserem MySleep-Handler zurückkehrt, die Daten des Shellcodes und stellen den Schutz wieder auf RX.
PAGE_READWRITE funktioniert wie folgtkernel32!Sleep, sodass er auf unseren Callback zeigt.VirtualAlloc + memcpy + CreateThread. Im Gegensatz zu dem, was wir in ThreadStackSpoofer hatten, hooken wir hier nichts in ntdll, um unseren Shellcode zu starten, sondern springen stattdessen von unserer eigenen Funktion aus zu ihm. Dies versucht, einfache IOCs im Speicher zu vermeiden, die auf modifizierten ntdll-Speicher hinweisen.MySleep-Callback aufgerufen.RW umgestellt.kernel32!Sleep-Funktion, um einfache IOCs im Speicher zu vermeiden, die darauf hindeuten, dass Sleep getrampolint (in-line gehooked) wurde.::Sleep-Funktion erfolgt, um Beacon schlafen zu lassen, während auf weitere Kommunikation gewartet wird.RX und hooken kernel32!Sleep erneut, um die Abfangung nachfolgender Schlafphasen sicherzustellen.PAGE_NOACCESS funktioniert wie folgtkernel32!Sleep, sodass er auf unseren Callback zeigt.VirtualAlloc + memcpy + CreateThread ...MySleep-Callback aufgerufen.PAGE_NOACCESS umgestellt.kernel32!Sleep-Funktion, um einfache IOCs im Speicher zu vermeiden, die darauf hindeuten, dass Sleep getrampolint (in-line gehooked) wurde.::Sleep-Funktion erfolgt, um Beacon schlafen zu lassen, während auf weitere Kommunikation gewartet wird.kernel32!Sleep erneut, um die Abfangung nachfolgender Schlafphasen sicherzustellen.RX um, und der Shellcode wird fortgesetzt.Die Technik ist nicht brandneu und nichts, was ich mir selbst ausgedacht habe. Sie ist lediglich eine Implementierung, die das Konzept und seine praktische Nutzung zeigt, damit unsere Offensive-Security-Community mit dem Angebot kommerzieller C2-Frameworks aufholen kann.
Eigentlich wurde ich vor ein paar Jahren durch die Arbeit von Josh Lospinoso in seinem erstaunlichen Gargoyle mit der Idee vertraut gemacht, den Speicherschutz von Shellcode umzustellen.
Hier gibt es weitere Hintergrundinformationen:
Gargoyle führt das Konzept von selbstbewusstem und selbstfluktuierendem Shellcode noch weiter, indem es eine ROP-Sequenz nutzt, die VirtualProtect aufruft.
Die Technik ist jedoch beeindruckend, aber ebenso schwer mit Cobalt Strikes Beacon einzusetzen, ohne dessen Thread zu beenden und Beacon während des Betriebs im Speicher immer wieder neu zu initialisieren.
Das ist alles andere als perfekt, aber da wir bereits von den Grundlagen unseres eigenen Selbstinjektions-Loader-Prozesses aus operieren, können wir mit der Umgebung, in der der Shellcode arbeitet, machen, was wir wollen, und ihn verbergen, wie wir möchten. Diese Technik (und die vorherige, ThreadStackSpoofer) zeigt Vorteile, wenn wir unsere Shellcodes auf diese Weise ausführen.
Die Implementierung der Fluktuation zu PAGE_NOACCESS ist inspiriert von der Arbeit von ORCA666, die in seinem https://github.com/ORCA666/0x41-Injektor vorgestellt wurde.
Er zeigte, dass: