Function used in specific attacks
Funkcje używane przy konkretnych metodach wstrzyknięcia kodu | |
DLL Injection | |
this old technique is used to force a process to load a DLL. Main potentially involved APIs: OpenProcess( ), VirtualAllocEx( ), WriteProcessMemory and CreateRemoteThreat | NtCreateThread( ) | RtlCreateUserThread( ). | CreateToolhelp32Snapshot, Process32First, and Process32Next – to search the process list for the injection target |
The DLL injection launcher’s goal is to call CreateRemoteThread in order to create the remote thread LoadLibrary, with the parameter of the malicious DLL being injected. | |
Direct injection | |
VirtualAllocEx, WriteProcessMemory, and CreateRemoteThread. There will typically be two calls to VirtualAllocEx and WriteProcessMemory. The first will allocate and write the data used by the remote thread, and the second will 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). | |
PE Injection | |
in this technique a malicious code is written and, consequently, forced to be executed in a remote process or even in the own process (self-injection). | OpenThread( ), SuspendThread( ), VirtualAllocEx( ), WriteProcessMemory( ), SetThreatContext( ) and ResumeThreat( ) | NtResumeThread( ). |
Reflective Injection: | |
this technique is similar to PE Injection, but the malicious code avoid using LoadLibrary( ) and CreateRemoteThread( ), for example. There’re many interesting derivations of this method and, one of them (also used on Cobalt Strike) is accomplished by the following APIs: | CreateFileMapping( ), Nt/MapViewOfFile( ), OpenProcess( ), memcpy( ) and Nt/MapViewOfSection( ). At end, code on remote process can be executed by calling OpenProcess( ), CreateThread( ), NtQueueApcThread( ), CreateRemoteThread( ) or RtlCreateUserThread( ). It’s interesting to note that a variant could use VirtualQueryEx( ) and ReadProcessMemory( ) too. |
APC Injection: | |
this code injection technique allows a program to execute code in a specific thread by attaching to an APC queue. The injected code will be executed by the thread when it exits of alertable state | SleepEx( ), SignalObjectAndWait( ), MsgWaitForMultipleObjectsEx( ), WaitForMultipleObjectsEx( ), WaitForSingleObjectEx( ), CreateToolhelp32Snapshot(), Process32First( ), Process32Next( ), Thread32First( ), Thread32Next( ), QueueUserAPC( ) and KeInitializeAPC( ) |
Asynchronous Procedure Call WaitForSingleObjectEx is the most common call in the Windows API – from User Space (user-mode – that means generated for an application) | |
APC Injection from User Space (generated for an application) | During analysis, you can find thread-targeting code by looking for API calls such as CreateToolhelp32Snapshot, Process32First, and Process32Next for the malware to find the target process. These API calls will often be followed by calls to Thread32First and Thread32Next, which will be in a loop looking to target a thread contained in the target process. Alternatively, malware can also use Nt/ZwQuerySystemInformation with the SYSTEM_PROCESS_INFORMATION information class to find the target process. |
Hollowing or Process Replacement | |
this technique, in a nutshell, is used by the malware to “drain out” the entire content of a process and insert into it a malicious content. | CreateProcess( ), NtQueryProcessInformation( ), GetModuleHandle( ), Zw/NtUnmapViewOfSection( ), VirtualAllocEx( ), WriteProcessMemory( ), GetThreadContext( ), SetThreadContext ( ) and ResumeThread( ). |
AtomBombing: | |
this technique is an a variant of the previous technique (APC injection) and works by splitting the malicious payload into separated strings, creating an Atom to each given string, copying them into a RW segment | GlobalGetAtomName( ) and NtQueueApcThread( )) and setting the context by using NtSetContextThread( ). Therefore, a list of further APIs are OpenThread( ), GlobalAddAtom( ), GlobalGetAtomName( ) and QueueUserAPC( ). |
Process Doppelgänging: | |
this technique could be handled as a kind of evolution of Process Hollowing. The key difference between this both techniques is that while Process Hollowing replaces the process’s content (image) before it being resumed, Process Doppelgänging is able to replace the image before the process even being created by overwriting the target image with a malicious one before it being loaded. The key concept here is that NTFS operations are performed within transactions, so either all these operations inside a transactions are committed together or none of them are committed. In the meanwhile, the malicious image only exists and it’s visible inside the transaction and it isn’t visible to any other process. Therefore, the malicious image is loaded into memory and the malware drops the malicious payload from file system (by rollbacking the transaction) as the file never had existed previously. | CreateTransaction( ), CreateFileTransaction( ), NtCreateSection, NtCreateProcessEx( ), NtQueryInformationProcess( ), NtCreateThreadEx( ) and RollbackTransaction( ). |
Process Herpaderping | |
this technique is similar to Process Doppelgänging, but there’s a subtle difference in its procedure. Process Herpaderping is based on that fact that security defenses usually monitor process creation by registering a callback routine on the kernel side using PsSetCreateProcessNotifyRoutineEx( ) or during driver’s DispatchCleanup routines (IRP_MJ_CLEANUP), which it is invoked after a thread being created. That’s the key issue: if the an adversary create and map a process and, afterwards, this adversary is able to modify the file image and then create the thread, so security products are able to detect such a malicious payload. Nonetheless, this checking order can be comprised whether the adversary is able to create malicious binary on disk, open a handle to it, map it as an image section using NtCreateSection function (and including the SEC_IMAGE flag), create a process using the section handle (NtCreateProcesEx()), modify the file content to not sounds like malicious and create a thread (NtCreateThreadEx()) using this “good image”. That the point: when the thread is created, the process callback is triggered and the content of the file (good one) on disk is checked, so security defenses believes that everything is fine because image on disk is not harmful, but the true malicious is on memory. In other words, security defenses could not be effective to detect such image on disk that is different from image on memory. | CreateFile( ), NtCreateSection( ), NtCreateProcessEx( ) and NtCreateThreadEx( ). |
Hooking Injection | |
to use this technique, we will see that functions involved with hooking activities such as SetWindowsHookEx( ) and PostThreadMessage( ) are used to inject a malicious DLL. | |
Extra Windows Memory Injection | |
using this technique, malware threats injects code into the a process by using the Extra Windows Memory (as known as EWM), whose size is up to 40 bytes and it’s appended the instance of a class during the registration of windows classes. The trick is that the appended spaced is enough to store a pointer that might forward the execution to a malicious code. | FindWindowsA( ), GetWindowThreadProcessId( ), OpenProcess( ), VirtualAllocEx( ), WriteProcessMemory( ), SetWindowLongPtrA( ) and SendNotify( ). |
Propagate Injection | |
this technique has been used by malware threats such as RIG Exploit Kit and Smoke Loader to inject malicious code into explorer.exe process (medium integrity level) and other persistent ones, and it’s based on the approach of enumerating (EnumWindows( ) → EnumWindowsProc → EnumChildWindows( ) → EnumChildWindowsProc → EnumProps( ) → EnumPropsProc → GetProp) windows implementing SetWindowsSubclass( ) (this further information on https://docs.microsoft.com/en-us/windows/win32/api/commctrl/nf-commctrl-setwindowsubclass). As you could remember, this function install a windows subclass callback and, as you know, callbacks are interpreted as hooking methods in the security world. How does it works? Once subclassed windows are found (checking UxSubclassInfo and/or CC32SubclassInfo, which provide the subclass header), it’s possible to preserve the old windows procedure, but we can also assign a new one to the window by updating CallArray field. When an event to the target process is sent then the new procedure is called and, afterwards, the old one is also called (keepingthe previous and expected behavior). Therefore, a malware inserts a malicious payload (shellcode) into the memory and updates subclass procedure using SetPropA( ). When this new property is invoked (through a windows message) , the execution is forwarded to the payload. | FindWindow( ), FindWindowEx( ), GetProp( ), GetWindowThreadProcessId( ), OpenProcess( ), ReadProcessMemory( ), VirtualAllocEx( ), WriteProcessMemory( ), SetProp( ) and PostMessage( ). |