Add Ekko / Sleep Obfuscation to Sliver
Card
This PR implements Ekko / in-memory sleep obfuscation for a beacon.
Details
Based on the work of https://github.com/scriptchildie/goEkko, adapted from https://github.com/Cracked5pider/Ekko, it pauses Go runtime and encrypts the beacon's memory region with the Ekko technique.
Command -B / --sleep-obfuscation added on generate beacon to support this feature. Only applicable for Windows.
Beacon while performing operations / active:
Beacon while in its sleep duration:
Looks awesome we'll try to get this reviewed and merged shortly!
Heya, @rkervella !
Thanks for the first review. Cleaned out the prints and randomised XOR key generation. Tested it again and looking through process hacker, functionality remains the same after the changes.
Alright, I finally started testing this, and I couldn't get the beacon process to self-encrypt when sleeping:
I tried with a debug beacon to confirm Ekko is properly called, and it is.
I also noticed the beacons using --sleep-obfuscation don't reach back to the server after a while, even if the process is still running.
Hey, @rkervella,
Busy time of the year.
I believe the self-encryption is working as intended. If you reconfig the beacon to have short sleep time (a few seconds) you'll see the memory address changing from RW to RWX whenever it's time for the beacon callback. To make this easier to spot, I've generated a beacon without shikata ga nai nor symbol obfuscation (-G -l) and if you re-read the same memory section you'll see it getting unencrypted/encrypted as expected:
while awake, RWX:
while sleeping, RW:
Well spotted on the process randomly hanging after some time. I've also found an old process hanging on a test server as you described. It appears that the memory region stays stuck in RWX and never self-encrypts/ goes back to sleep. I'll investigate what part of the code is hanging and get back to you with a fix, together with moving around the flags as you suggested!
Hey @armysick , I noticed that the transitions memory from RW to RWX instead of RX. I'm curious about the reasoning behind this choice.
Wouldn't changing to RWX make it easier for an EDR to detect suspicious behavior? A more common approach is to transition from RW to RX (Havoc example), which might be less noticeable. Is there a specific advantage to using RWX in this case?
Looking forward to your thoughts—thanks!