
Eine Variante von Gargoyle für x64, um Speicherartefakte zu verstecken, die nur ROP und PIC verwendet
Eine Variante von Gargoyle für x64, die Speicherartefakte nur mit ROP und PIC verbirgt.
Großer Dank geht an @waldoirc für die Dokumentation großer Teile dieser Technik in seinem Blog Diese Implementierung unterscheidet sich dadurch, dass sie keine APCs verwendet und vollständig als PIC implementiert ist.
Ich habe dies erstellt, um besser zu verstehen, wie man Speicherartefakte mit einer Gargoyle-ähnlichen Technik auf x64 umgehen kann. Die Idee ist, eine ROPChain einzurichten, die VirtualProtect() -> Sleep() -> VirtualProtect() aufruft, um meine eigene Seite während des Schlafens als N/A zu markieren.
Im Gegensatz zu Gargoyle und anderen Gargoyle-ähnlichen Implementierungen verlasse ich mich vollständig auf ROP und stelle keine APCs in die Warteschlange. DeepSleep selbst ist als vollständig PIC implementiert, was es einfacher macht, die Speicherseiten aufzulisten, die vor Scannern verborgen werden müssen.
Während der Thread aktiv ist, erscheint ein MessageBox und die Seite von DeepSleep wird als ausführbar markiert. Während des Schlafens wird die Seite als N/A markiert.
Dies umgeht effektiv Moneta zum Zeitpunkt des Verfassens, wenn DeepSleep injiziert wird und die Basisadresse des ausführenden Threads nicht auf privaten festgeschriebenen Speicher verweist.
Ich habe dies mit der Earlybird-Injektionstechnik verifiziert, um DeepSleep.bin in notepad.exe zu injizieren.

Mit Mingw:
Gebe make ein und eine wilde DeepSleep.bin erscheint.
Alternativ verwende die vorkompilierte DeepSleep.bin :-)
Ich könnte einen Loader für CS oder andere C2-Agenten veröffentlichen. Ähnlich wie YouMayPasser würde der Loader Sleep mit HW-Breakpoints hooken, um verdächtige Modifikationen von kernel32.dll zu vermeiden.
Getestet auf 10.0.19044 N/A Build 19044
Die ROPgadgets, auf die ich mich verlasse, könnten in anderen Windows-Versionen nicht in ntdll.dll existieren. Es ist wahrscheinlich eine gute Idee, kleinere und generischere ROPgadgets zu verwenden und die Gadgets in mehr DLLs als ntdll.dll zu enumerieren.
Der Callstack zu einem Thread im DelayExecution-Zustand enthält unbekannte/manipulierte Speicherbereiche und zusätzlich Adressen von VirtualProtect(). Hunt-Sleeping-Beacons erkennt dies.
Es könnte möglich sein, diese Metrik auf andere C2 anzuwenden, die eine andere Technik verwenden, um zwischen Callbacks zu warten.

@waldoirc für die Dokumentation großer Teile der Technik hier @forrest Orr für Moneta Josh Lospinoso für die ursprüngliche Gargoyle-Technik