Users became more aware, so malware authors developed many techniques to blend and evade detection.
Launchers
A launcher(AKA. loader) is a type of malware that sets itself or another piece of malware for immediate or future covert execution.
NOTEcovert: secret or hidden.
The most common example is an executable or DLL in its own resources section.
We can detect such activity with API functions such as: FindResource, LoadResource, SizeofResource.
These malware launchers often must be run with UAC, normal process can’t perform all techniques in the chapter so UAC is needed.
Process Injection
The most common technique is process injection, injects code into another running process, and that process executes the malicious code without knowing. This technique is used to hide malicious behaviour and bypass host-based firewalls.
Can be detected with APIs such as VirtualAllocEx to allocate space in an external’s process memory and WriteProcessMemory to write data to that allocated space.
DLL Injection
DLL injection is a form of process injection where a remote process is forced to load a malicious DLL. It works by injection code into a remote process that calls LoadLibrary, hence, forcing the process to load that malicious DLL which calls the DllMain of that malicious DLL with as much access as the compromised process.
The process injection starts by getting a handler to the victim process, The most common way is to use CreateToolhelp32Snapshot, Process32First, and Process32Next to enumerate the process list.
Once the target is found, the launcher retrieves the PID of the target and then uses it to obtain a handle via OpenProcess.
The function CreateRemoteThread used for DLL injection to create and execute a new thread in the remote(target) process.
When CreateRemoteThread is used, three parameters are passedhProcess -> process handle obtained with OpenProcess, lpStartAddress -> starting point of the injected thread, lpParameter -> a pointer to a variable to be passed to the thread function.
The starting point might be set to LoadLibrary and the malicious DLL name passed as the argument; this will trigger LoadLibrary to be run in the victim process with a parameter of the malicious DLL causing the DLL to be loaded in the victim process(assuming that LoadLibrary is available in the victim process’s memory space and the malicious library name string exists within that same space).
Authors generally use VirtualAllocEx to create space for the malicious library name string, it allocates space in a remote process if a handle to that process is provided.
The last function required before CreateRemoteThread can be called is WriteProcessMemory. It writes the malicious library name string into the memory space that was allocated using VirtualAllocEx.
Direct Injection
Direct injection involves allocating and inserting code into the memory space of a remote process. It involves same Windows API calls as DLL injection, but instead it injects the payload into the remote process memory. It’s more flexible than DLL injection but requires a lot of customised code. It can be used to inject compiled code, but more often it’s used to inject shellcode.
It usually employs three functions: VirtualAllocEx, WriteProcessMemory, and CreateRemoteThread. It starts by two calls to VirtualAllocEx and WriteProcessMemory, the first will allocate and write the data used by the remote thread, then the 2nd call will allocated and write the allocate and write the remote thread code. The call to CreateRemoteThread will contain the location of the remote thread code lpStartAddress and the data lpParameter. Direct injection requires the author to be skilled in Assembly or inject a simple shellcode.
In order to analyse remote thread’s code, you may need to dump all memory buffers that occur before calls to WriteProcessMemory, since they usually come in the form of shellcode; this will be further discussed in chapter 19.
Process Replacement
Process replacement is used to overwrite the memory of a running process in order to disguise as a legit process without the risk of crashing a process through injection.
It provides the malware with the same privileges as the replaced process. The key to this technique is creating a process in a suspended state, which means the process will be loaded into memory but the primary thread is suspended. The program won’t start unless an external program resumes the primary thread.
00401535 push edi ; lpProcessInformation00401536 push ecx ; lpStartupInfo00401537 push ebx ; lpCurrentDirectory00401538 push ebx ; lpEnvironment00401539 push CREATE_SUSPENDED ; dwCreationFlags0040153B push ebx ; bInheritHandles0040153C push ebx ; lpThreadAttributes0040153D lea edx, [esp+94h+CommandLine]00401541 push ebx ; lpProcessAttributes00401542 push edx ; lpCommandLine00401543 push ebx ; lpApplicationName00401544 mov [esp+0A0h+StartupInfo.dwFlags], 101h0040154F mov [esp+0A0h+StartupInfo.wShowWindow], bx00401557 call ds:CreateProcessAThis method can also be used to load a process into memory and suspend it at the entry point.
After process creation the target is replaced using ZwUnmapViewOfSection to release all memory pointed by a section passed as a parameter, then the loader performs VirtualAllocEx to allocated memory for the new payload, and uses WriteProcessMemory to writ each of malware sections to the target process.
Then context is restored using SetThreadContext to set the entry point to the injected payload and then ResumeThread is called to run the process again.
Read more from the attacker’s side
Hook Injection
Hook injection is a technique to load malware that takes advantage of windows hooks, which are used to intercept messages destined for other applications.
hook injection is used to ensure that malicious code will run whenever a particular message is intercepted and that a particular DLL will be loaded in a victim’s process’s memory space.
- Local Hooks are used to observe or manipulate messages destined for an internal process.
- Remote process are used to observe or manipulate another process on the system.
High-level remote hooks require the hook procedure to be an exported function contained in a DLL, which mapped by the OS into the process space of a hooked thread or all threads. While Low-Level remote hooks require the hook to be contained in the process that installed the hook. This procedure is notified before the OS gets a chance to process the event.
Keyloggers Using Hooks
Hook injection is frequently used in keyloggers by utilising the WH_KEYBOARD or WH_KEYBOARD_LL hook procedure types.
WH_KEYBOARD often will be running in the context of a remote process, but it can also run in the that installed the hook. As for WH_KEYBOARD_LL procedures, the events are sent directly to the process that installed the hook, so it will be running in the context of the process that created it. Using any of these hooks a keylogger can intercept key-strokes and log them to a file.
Using SetWindowsHookEx
The main function used for Windows hooking is SetWindowsHookEx, it has the following parameters:
- idHook -> Type of hook to install
- lpfn -> Pointer to hook procedure.
- hMod -> Handle to the Dll containing hook procedure defined by lpfn.
- dwThreadId -> Specifies the id of the thread associated with hook procedure if it’s zero, the hook is associated with all existing threads running in the same desktop as the calling thread(0 is mandatory for low-level hooks).
hook procedure is the code that process messages, it must call CallNextHookEx.
Thread Targeting(dwThreadId)
Malware generally includes instructions for for determining which system thread id to use or target all threads. Loading into all threads is a common behaviour of keyloggers or other software with the goal of message interception. However, loading into all threads can degrade the system and trigger IPS. Loading a single DLL in a remote process is better done by injecting a simple thread to remain stealthy.
Targeting a single thread requires enumerating the processes or run a program if the target is not run. If the hook was done to a common message it may trigger an IPS; so malware will hook with uncommon messages such as WH_CBT.
00401100 push esi00401101 push edi00401102 push offset LibFileName ; "hook.dll"00401107 call LoadLibraryA0040110D mov esi, eax0040110F push offset ProcName ; "MalwareProc"00401114 push esi ; hModule00401115 call GetProcAddress0040111B mov edi, eax0040111D call GetNotepadThreadId00401122 push eax ; dwThreadId00401123 push esi ; hmod00401124 push edi ; lpfn00401125 push WH_CBT ; idHook00401127 call SetWindowsHookExAIn this listing a malicious dll is loaded using LoadLibraryA and the malicious procedure is obtained using GetProcAddress, GetNotepadThreadId is a locally defined function that gets dwThreadId for notepad.exe. Finally, a WH_CBT message is sent to the injected notepad.exe. once hook.dll is injected it can execute code while disguised as notedpad.exe. Since MalwareProc calls only CallNextHookEx it shouldn’t interfere with incoming messages, but malware often call LoadingLibrary and UnhookWindowsHookEx in DllMain to ensure that incoming messages are not impacted.
Detours
A library developed by MS research in 1999. Was intended as a way to instrument and extend extend existing OS and app functions.
Detours library makes it possible for a developr to make applications modification simple. It’s used by malware authors to perform import table modifications, attach DLLs to existing program files, and functions hooks to running process.
The malware modifies .detour section which is typically placed between the export table and any debug symbols, it contains the original PE header with a new import address table. Authors use the Detours to modify the PE header to point to the new import table.
APC Injection
Thread creation requires overhead, so it’s more efficient to invoke a function on an existing thread, this exists in Windows as Asynchronous Procedure Call(APC).
APCs can direct a thread to execute some other code prior to executing its regular execution path. Every thread has a queue of APCs attached to it, and these are processed when the thread is in alertable state e.g: WaitForSingleObjectEx, WaitForMultipleObjectsEx, and Sleep.
These functions essentially give. APC is used to run code in threads when they are alertable(before starting) so when the APC queue is complete the thread continuous running in its normal path; basically running the code immediately.
- APC for the system or a driver -> kernel-mode APC.
- APC for an application -> user-mode APC
APC injection from User Space
The thread queues a function to be invoked in another thread using QueueUserAPC. Because a thread must be alertable, malware will look to target threads in processes that are like to be alertable, WaitForSingleObjectEx is the most common call for this technique.
QueueUserAPC call is a request for the thread whose handle is hThread, to run the function defined in pfnAPC with the parameter dwData.
TIPAPI calls
CreateToolHelp32Snapshot,Process32First,Process32Nextmay be found during analysis to look for target process, they will often be followed byThread32FirstandThread32Next, which will be also in a loop looking to target a thread contained in target process. Malware Can also useNt/ZwQuerySystemInformationwithSYSTEM_PROCESS_INFORMATIONclass to find the target process.
00401DA9 push [esp+4+dwThreadId] ; dwThreadId00401DAD push 0 ; bInheritHandle00401DAF push 10h ; dwDesiredAccess00401DB1 call ds:OpenThread00401DB7 mov esi, eax00401DB9 test esi, esi00401DBB jz short loc_401DCE00401DBD push [esp+4+dwData] ; dwData = dbnet.dll00401DC1 push esi ; hThread00401DC2 push ds:LoadLibraryA ; pfnAPC00401DC8 call ds:QueueUserAPCOnce a thread is found, the malware uses it to open a handle to the tread OpenThread(4), the malware then is looking to force the thread to load dbnet.dll library(10) as LoadLibraryA is passed to pfnAPC and dbnet.dll is passed as dwData. so it runs LoadLibrary(dbnet.dll).
APC injection from Kernel Space
There’s no easy way for drivers to execute code in user space. One method is to perform APC injection from kernel space.
A malicious driver can build an APC and dispatch a thread to execute it in a user-mode process (mostly svchost.exe). These APCs mostly contain shellcode.
The driver uses two functions KeInitialiseApc and KeInsertQueueApc to initialise a call to KeInitializeApc, if the sixth parameter (NormalRoutine)(2) non-zero in combination with the seventh-parameter (AcpMode)(1) being set to 1 then we are looking for a user-mode type.
KeInitializeApc initis a KAPC structure which must be passed KeInsertQueueApc to place APC in the queue.
000119BD push ebx000119BE push 1000119C0 push [ebp+arg_4]000119C3 push ebx000119C4 push offset sub_11964000119C9 push 2000119CB push [ebp+arg_0]000119CE push esi000119CF call ds:KeInitializeApc000119D5 cmp edi, ebx000119D7 jz short loc_119EA000119D9 push ebx000119DA push [ebp+arg_C]000119DD push [ebp+arg_8]000119E0 push esi000119E1 call edi ;KeInsertQueueApcSome information may be outdated