一种针对 x64 的 Gargoyle 变体,仅使用 ROP 和 PIC 隐藏内存痕迹。
衷心感谢 @waldoirc 在他的 博客 中记录了此技术的大部分内容。
此实现的不同之处在于它不使用任何 APC,并且完全以 PIC 形式实现。
我创建此工具是为了更好地理解如何在 x64 上使用类似 Gargoyle 的技术规避内存痕迹。 其思路是设置一个 ROP 链,依次调用 VirtualProtect() -> Sleep() -> VirtualProtect(),以便在 Sleep 期间将自己的页面标记为 N/A。
与 Gargoyle 及其他类似实现不同,我完全依赖 ROP,并且不排队任何 APC。 DeepSleep 本身完全以 PIC 实现,这使得更容易枚举需要向扫描器隐藏的内存页面。
线程活动时,会弹出一个 MessageBox,DeepSleep 的页面被标记为可执行。线程休眠时,该页面被标记为 N/A。
如果 DeepSleep 被注入,并且执行线程的基地址不指向私有提交内存,则此方法在撰写本文时可有效绕过 Moneta。
我已使用 Earlybird 注入技术将 DeepSleep.bin 注入到 notepad.exe 中,对此进行了验证。

使用 Mingw:
输入 make,一个狂野的 DeepSleep.bin 就会出现。
或者直接使用预编译的 DeepSleep.bin :-)
我可能会为 CS 或其他 C2 代理发布一个加载器。类似于 YouMayPasser,该加载器将使用硬件断点挂钩 sleep,以避免对 kernel32.dll 的可疑修改。
已在 10.0.19044 N/A Build 19044 上进行测试。
我所依赖的 ROPgadget 可能在其他 Windows 版本的 ntdll.dll 中不存在。 最好使用更小、更通用的 ROPgadget,并在除 ntdll.dll 之外的更多 DLL 中枚举 gadget。
处于 DelayExecution 状态的线程的调用栈包含未知/篡改的内存区域,并且还包含 VirtualProtect() 的地址。 Hunt-Sleeping-Beacons 可以检测到这一点。
可能可以将该指标应用于使用不同技术在回调之间等待的其他 C2。

@waldoirc 在 此处 记录了该技术的大部分内容
@forrest Orr 提供了 Moneta
Josh Lospinoso 提供了原始的 Gargoyle 技术