ShellcodeFluctuation
An advanced in-memory evasion technique fluctuating shellcode's memory protection between RW/NoAccess & RX and then encrypting/decrypting its contents
Install / Use
/learn @mgeeky/ShellcodeFluctuationREADME
Shellcode Fluctuation PoC
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.
Intro
After releasing ThreadStackSpoofer I've received a few questions about the following README's point:
Change your Beacon's memory pages protection to RW (from RX/RWX) and encrypt their contents before sleeping (that could evade scanners such as Moneta or pe-sieve)
Beforewards I was pretty sure the community already know how to encrypt/decrypt their payloads and flip their memory protections to simply evade memory scanners looking for anomalous executable regions. Questions proven otherwise so I decided to release this unweaponized PoC to document yet another evasion strategy and offer sample implementation for the community to work with.
This PoC is a demonstration of rather simple technique, already known to the offensive community (so I'm not bringin anything new here really) in hope to disclose secrecy behind magic showed by some commercial frameworks that demonstrate their evasion capabilities targeting both aforementioned memory scanners.
Here's a comparison when fluctuating to RW (another option is to fluctuate to PAGE_NOACCESS - described below):
- Beacon not encrypted
- Beacon encrypted (fluctuating)

This implementation along with my ThreadStackSpoofer brings Offensive Security community sample implementations to catch up on the offering made by commercial C2 products, so that we can do no worse in our Red Team toolings. 💪
How it works?
This program performs self-injection shellcode (roughly via classic VirtualAlloc + memcpy + CreateThread).
When shellcode runs (this implementation specifically targets Cobalt Strike Beacon implants) a Windows function will be hooked intercepting moment when Beacon falls asleep kernel32!Sleep.
Whenever hooked MySleep function gets invoked, it will localise its memory allocation boundaries, flip their protection to RW and xor32 all the bytes stored there.
Having awaited for expected amount of time, when shellcode gets back to our MySleep handler, we'll decrypt shellcode's data and flip protection back to RX.
Fluctuation to PAGE_READWRITE works as follows
- Read shellcode's contents from file.
- Hook
kernel32!Sleeppointing back to our callback. - Inject and launch shellcode via
VirtualAlloc+memcpy+CreateThread. In contrary to what we had inThreadStackSpoofer, here we're not hooking anything in ntdll to launch our shellcode but rather jump to it from our own function. This attempts to avoid leaving simple IOCs in memory pointing at modified ntdll memory. - As soon as Beacon attempts to sleep, our
MySleepcallback gets invoked. - Beacon's memory allocation gets encrypted and protection flipped to
RW - We then unhook original
kernel32!Sleepto avoid leaving simple IOC in memory pointing thatSleephave been trampolined (in-line hooked). - A call to original
::Sleepis made to let the Beacon's sleep while waiting for further communication. - After Sleep is finished, we decrypt our shellcode's data, flip it memory protections back to
RXand then re-hookkernel32!Sleepto ensure interception of subsequent sleep.
Fluctuation to PAGE_NOACCESS works as follows
- Read shellcode's contents from file.
- Hook
kernel32!Sleeppointing back to our callback. - Inject and launch shellcode via
VirtualAlloc+memcpy+CreateThread... - Initialize Vectored Exception Handler (VEH) to setup our own handler that will catch Access Violation exceptions.
- As soon as Beacon attempts to sleep, our
MySleepcallback gets invoked. - Beacon's memory allocation gets encrypted and protection flipped to
PAGE_NOACCESS - We then unhook original
kernel32!Sleepto avoid leaving simple IOC in memory pointing thatSleephave been trampolined (in-line hooked). - A call to original
::Sleepis made to let the Beacon's sleep while waiting for further communication. - After Sleep is finished, we re-hook
kernel32!Sleepto ensure interception of subsequent sleep. - Shellcode then attempts to resume its execution which results in Access Violation being throwed since its pages are marked NoAccess.
- Our VEH Handler catches the exception, decrypts and flips memory protections back to
RXand shellcode's is resumed.
It's not a novel technique
The technique is not brand new, nothing that I've devised myself. Merely an implementation showing the concept and its practical utilisation to let our Offensive Security community catch up on offering made by commercial C2 frameworks.
Actually, I've been introduced to the idea of flipping shellcode's memory protection couple of years back through the work of Josh Lospinoso in his amazing Gargoyle.
Here's more background:
- gargoyle, a memory scanning evasion technique
- Bypassing Memory Scanners with Cobalt Strike and Gargoyle
Gargoyle takes the concept of self-aware and self-fluctuating shellcode a way further, by leveraging ROP sequence calling out to VirtualProtect.
However the technique is impressive, its equally hard to leverage it with Cobalt Strike's Beacon without having to kill its thread and keep re-initializing Beacon while in memory.
That's far from perfect, however since we already operate from the grounds of our own self-injection loader process, we're able to do whatever we want with the environment in which shellcode operate and hide it however we like. This technique (and the previous one being ThreadStackSpoofer) shows advantages from running our shellcodes this way.
The implementation of fluctuating to PAGE_NOACCESS is inspired by ORCA666's work presented in his https://github.com/ORCA666/0x41 injector.
He showed that:
- we can initialize a vectored exception handler (VEH),
- flip shellcode's pages to no-access
- and then catch Access Violation exceptions that will occur as soon as the shellcode wants to resume its execution and decrypt + flip its memory pages back to Read+Execute.
This implementation contains this idea implemented, available with option 2 in <fluctuate>.
Be sure to check out other his projects as well.
Demo
The tool ShellcodeFluctuation accepts three parameters: first one being path to the shellcode and the second one modifier of our functionality.
Usage: ShellcodeFluctuation.exe <shellcode> <fluctuate>
<fluctuate>:
-1 - Read shellcode but dont inject it. Run in an infinite loop.
0 - Inject the shellcode but don't hook kernel32!Sleep and don't encrypt anything
1 - Inject shellcode and start fluctuating its memory with standard PAGE_READWRITE.
2 - Inject shellcode and start fluctuating its memory with ORCA666's PAGE_NOACCESS.
Moneta (seemingly) False Positive
C:\> ShellcodeFluctuation.exe beacon64.bin -1
So firstly we'll see what Moneta64 scanner thinks about process that does nothing dodgy and simply resorts to run an infinite loop:

As we can see there's some false positive (at least how I consider it) allegdly detecting Mismatching PEB module / Phantom image.
The memory boundaries point at the ShellcodeFluctuate.exe module itself and could indicate that this module however being of MEM_IMAGE type, is not linked in process' PEB - which is unsual and sounds rather odd.
The reason for this IOC is not known to me and I didn't attempt to understand it better, yet it isn't something we should be concerned about really.
If anyone knows what's the reason for this detection, I'd be very curious to hear! Please do reach out.
Not Encrypted Beacon
C:\> ShellcodeFluctuation.exe beacon64.bin 0
The second use case presents Memory IOCs of a Beacon operating within our process, which does not utilise any sorts of customised Artifact Kits, User-Defined Reflective Loaders (such as my ElusiveMice), neither any initial actions that would spoil our results.

We can see that Moneta64 correctly recognizes Abnormal private executable memory pointing at the location where our shellcode resides.
That's really strong Memory IOC exposing our shellcode for getting dumped and analysed by automated scanners. Not cool.
Encrypted Beacon with RW protections
C:\> ShellcodeFluctuation.exe beacon64.bin 1
Now the third, most interesting from perspective of this implementation, use case being fluctuating Beacon.

Apart from the first IOC, considered somewhat false positive, we see a new one pointing that kernel32.dll memory was modified.
However, no Abnormal private executable memory IOC this time. Our fluctuation (repeated encryption/decryption and memory protections flipping is active).
And for the record, pe-sieve also detects implanted PE when used with /data 3 option (unless this option is given, no detection will be made):

My current assumption is t
Related Skills
docs-writer
99.3k`docs-writer` skill instructions As an expert technical writer and editor for the Gemini CLI project, you produce accurate, clear, and consistent documentation. When asked to write, edit, or revie
model-usage
339.1kUse CodexBar CLI local cost usage to summarize per-model usage for Codex or Claude, including the current (most recent) model or a full model breakdown. Trigger when asked for model-level usage/cost data from codexbar, or when you need a scriptable per-model summary from codexbar cost JSON.
project-overview
FlightPHP Skeleton Project Instructions This document provides guidelines and best practices for structuring and developing a project using the FlightPHP framework. Instructions for AI Coding A
Design
Campus Second-Hand Trading Platform \- General Design Document (v5.0 \- React Architecture \- Complete Final Version)1\. System Overall Design 1.1. Project Overview This project aims t
