S3cur3Th1sSh1t
Some days ago I woke up in the middle of the night - thinking about the Advapi32.dll
/SystemFunction032
function. Really? Yes. Strange, this InfoSec folks. This post will show my nightly idea and sample Code on how to weaponize it.
SystemFunction032??
I did not know about this function before digging into Sleep obfuscation techniques like Foliage or Ekko. Although Benjamin Delphi already wrote about it in 2013 and used it in Mimikatz.
So this function is able to encrypt/decrypt memory regions via RC4 encryption. As for example the ReactOS Code shows it takes a pointer to an RC4_Context structure as input as well as a pointer to the encryption key:

“Why the heck do you see something special in that?” you could ask. Well, at least I personally did not know about alternative functions for existing memory region
encryption/decryption except for XOR
operations. But as you can read in for example Kyle Avery’s blog about Avoiding Memory Scanners a simple XOR
even with a longer key got in the meanwhile to detect for AV/EDR vendors.
Although RC4 is considered as insecure and even broken for years it provides a much better memory evasion for e.G. Shellcode to us than simple XOR
. It would be even more OpSec save to use AES here instead. But one single Windows API is at least very easy to use.
The midnight idea
Typically if you want to execute Shellcode in a process you will need the following steps:
- Open a Handle to the Process
- Allocate Memory in that Process with
RW/RX
orRWX
permissions - Write the Shellcode into that region
- (Optional) change Permissions to
RX
fromRW
for execution - Execute the Shellcode as Thread/APC/Callback/whatever
To avoid signature based detections we could encrypt our Shellcode and decrypt that on runtime before execution. For e.g. AES decryption the flow would typically look like this:
- Open a Handle to the Process
- Allocate Memory in that Process with
RW/RX
orRWX
permissions - Decrypt the Shellcode, so that we can write the cleartext value into memory
- Write the Shellcode into the allocated region
- (Optional) change Permissions to
RX
fromRW
for execution - Execute the Shellcode as Thread/APC/Callback/whatever
In this case, the Shellcode itself could get detected when writing it into memory e.g. by userland hooks as we would need to pass a pointer of the cleartext Shellcode to WriteProcessMemory
or NtWriteVirtualMemory
.
The usage of XOR
could avoid that, because we can even XOR
decrypt the memory region after writing the encrypted value into memory. It would look like this:
- Open a Handle to the Process
- Allocate Memory in that Process with
RW/RX
orRWX
permissions - Write the Shellcode into the allocated region
- XOR decrypt the Shellcode memory region
- (Optional) change Permissions to
RX
fromRW
for execution - Execute the Shellcode as Thread/APC/Callback/whatever
But XOR
can easily be detected. So we don’t want to use that. You already got the idea?
As an alternative we could make use of SystemFunction032
to decrypt the Shellcode after writing it into memory. So let’s do that!
The PoC
First I had the idea of generating Shellcode and just RC4 encrypt it with OpenSSL. So my idea was to generate it as follows:
But later on - when debugging - it turned out, that SystemFunction032
somehow encrypts/decrypts different to OpenSSL/RC4. So we cannot do it like that.
09.11.2022: Update
an0n_r0 gave further information on how to do the encryption with OpenSSL. You can do it as follows:
We could also use the following Nim Code to get an encrypted Shellcode blob (Windows OS only):
09.11.2022: Update
snovvcrash also published a simple Python Script after this blog which simplifies the encryption with a Python Script:
To execute this, we could simply use the following Nim code:
At least Defender does not complain here:

By using that we can nearly ignore userland hooks because our cleartext Shellcode is never passed to any function (Only SystemFunction032
itself). Of course, all those vendors could detect us by hooking Advapi32/SystemFunction032
- I did ask this question into the InfoSec community regarding to Sleep obfuscation detection some time ago.
But:
- There seam to be some privacy reasons why vendors can’t easily hook it, because they would get too many sensitive informations out of legitimate Processes.
- There are many alternatives to
SystemFunction032
, just read the Benjamin Delphi article linked above or take a look at the ReactOS code. - We could also unhook the function before using it.
At the moment at least vendors seam to not hook it. I personally guess this will change in the future.
Homework for the interested
Another idea was even better from my mind. By using PIC-Code we could also skip all other Win32 functions which were used in my PoC. Because when writing PIC-Code, all code is contained in the .text
section, and this section typically has RX
permissions by default, which is enough many times. So we would not need to change memory permissions and we don’t need to write the Shellcode to memory.
It would just be as short as follows:
- Call
SystemFunction032
to decrypt the Shellcode - Directly call it
Sample Code for PIC-Code can for example be found here. For the Nim-Fans, one library was released ~2 weeks ago which also enables us to relatively easy write PIC-Code called Bitmancer.
Is a program, that just calls SystemFunction032
potentially malicious? :-) Or one, that just calls any other encryption/decryption function?
Links & Resources
- Foliage https://github.com/SecIdiot/FOLIAGE
- Ekko https://github.com/Cracked5pider/Ekko
- Avoiding Memory Scanners blog https://www.blackhillsinfosec.com/avoiding-memory-scanners/
- SystemFunction032 Benjamin Delphi Post https://blog.gentilkiwi.com/tag/systemfunction032
- ReactOS Code SystemFunction032 https://doxygen.reactos.org/df/d13/sysfunc_8c.html#a66d55017b8625d505bd6c5707bdb9725
- PIC Hello World code https://github.com/thefLink/C-To-Shellcode-Examples/blob/master/HelloWorld/HelloWorld.c
- Bitmancer Library https://github.com/zimawhit3/Bitmancer