Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Ekko / Sleep Obfuscation to Sliver #1805

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

armysick
Copy link

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_Active

Beacon while in its sleep duration:
Beacon_Sleeping

@armysick armysick requested a review from a team as a code owner October 31, 2024 01:07
@moloch--
Copy link
Member

Looks awesome we'll try to get this reviewed and merged shortly!

Copy link
Member

@rkervella rkervella left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple of things to changes before I can dynamically test that one:

  • please don't print to stdout when you're not in debug mode
  • generate the XOR key dynamically at runtime instead of the hardcoded buffer of 0x55 values.

implant/sliver/ekko/ekko.go Outdated Show resolved Hide resolved
implant/sliver/ekko/ekko.go Outdated Show resolved Hide resolved
implant/sliver/ekko/ekko.go Outdated Show resolved Hide resolved
implant/sliver/ekko/ekko.go Outdated Show resolved Hide resolved
implant/sliver/ekko/ekko.go Outdated Show resolved Hide resolved
implant/sliver/ekko/ekko.go Outdated Show resolved Hide resolved
@armysick
Copy link
Author

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.

Copy link
Member

@rkervella rkervella left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just found a few more things that need to be changed.

@@ -307,6 +307,7 @@ func coreImplantFlags(name string, cmd *cobra.Command) {
f.BoolP("evasion", "e", false, "enable evasion features (e.g. overwrite user space hooks)")
f.BoolP("skip-symbols", "l", false, "skip symbol obfuscation")
f.BoolP("disable-sgn", "G", false, "disable shikata ga nai shellcode encoder")
f.BoolP("sleep-obfuscation", "B", false, "apply ekko in-memory sleep obfuscation")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be in coreBeaconFlags instead since sleep obfuscation is only relevant for beacons (unless I'm mistaken, feel free to correct me).

@@ -272,6 +272,7 @@ func parseCompileFlags(cmd *cobra.Command, con *console.SliverClient) (string, *
debug, _ := cmd.Flags().GetBool("debug")
evasion, _ := cmd.Flags().GetBool("evasion")
templateName, _ := cmd.Flags().GetString("template")
sleepObfuscation, _ := cmd.Flags().GetBool("sleep-obfuscation")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same idea, please move this to generate-beacon.go instead.

@rkervella
Copy link
Member

rkervella commented Dec 3, 2024

Alright, I finally started testing this, and I couldn't get the beacon process to self-encrypt when sleeping:
image

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.

@armysick
Copy link
Author

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:
image

while sleeping, RW:
image

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants