In security, process execution refers to the running of programs, code, or
commands within an operating system, which is a critical phase where
malicious activity often occurs. Attackers exploit this by using techniques
like process injection to run malicious code inside legitimate, trusted
processes to evade detection, gain elevated privileges, and mask their
actions.
Key Aspects of Process Execution in Security:
Process Injection (T1055): Adversaries inject malicious code into
the memory space of a running process (e.g., [Link]) to hide,
bypass security controls, and gain the permissions of that process.
Malicious Payloads: Instead of dropping malicious files to disk,
attackers often execute code directly in memory to avoid detection.
Privilege Escalation: By injecting code into a high-privilege
process, attackers can gain elevated, administrative, or system-level
access.
Detection & Defense: Security teams, such as SOCs, use tools to
monitor for suspicious process behavior, unexpected network
connections from processes, or unauthorized code injection, as
described on the MITRE ATT&CK® website.
Common Attack Techniques:
DLL Injection: Forcing a process to load a malicious Dynamic Link
Library.
Process Hollowing: Creating a legitimate process in a suspended
state, replacing its memory with malicious code, and resuming it.
Remote Code Execution (RCE): Triggering unauthorized code
execution through vulnerabilities in applications.
What is Process Injection?
Process injection allows a code to be injected into the memory space of
the other ongoing process. In this technique, the attacker forces the target
process to run arbitrary code by writing their own code into the address
space of that process. The code being injected executes under the context
and rights of the vulnerable process, thus, it inherits all of its access rights
and the trust level on the system.
Process injection consists of the following technical components at the
core: process handle acquisition, memory allocation in the target process,
code writing operations, and execution triggering mechanisms. They use
Windows API functions such as OpenProcess(), VirtualAllocEx(),
WriteProcessMemory(), and CreateRemoteThread() to execute the
injection process.
Why Process Injection is Dangerous?
Several technical aspects make this attack type relatively dangerous. The
code executed from the injected thread has the same privileges as the
target process, effectively resulting in elevated access to the system. This
method bypasses any file-based security scanning since the insecure code
exists only in memory.
It also has a serious effect on the stability and security of systems.
Injecting operations may get crashed by the target processes and
introduce instability across the system. They achieve this by terminating
security product processes, stealing data from protected applications, and
establishing persistent system access that evades common cleanup
techniques.
Process Memory Fundamentals
The technical basis for process injection techniques is the understanding
of process memory structures and operations. There are internal features
of the Windows OS memory management model that enable and also
restrict memory interactions and access between processes. They
instantly alter the way process injection works and the way defenders can
detect and protect against it.
Virtual Memory and Process Address Space
Each Windows process has its own virtual address space, isolated from
other processes running on the same system. The range of this virtual
address space is 0 to 0x7FFFFFFF for 32-bit processes and 0 to
0x7FFFFFFFFFF for 64-bit processes. Mapping from virtual addresses to
physical memory locations is done with the help of the paging technique
by the Windows Memory Manager.
The process has a number of regions in its address space, such as the
process executable code, loaded DLLs, heap allocations, and stack space.
These regions have specific functions and types of data. Windows has
page tables that describe where pages of memory frames are, and
whether they are in the virtual address space.
Memory Permissions and Protection
There are access permissions for memory regions, which describe how
processes should interact with them. These permissions include:
PAGE_EXECUTE: Memory can be executed as code
PAGE_READ: Memory can be read
PAGE_WRITE: Memory can be written to
PAGE_EXECUTE_READ: Memory can be executed and read
PAGE_EXECUTE_READWRITE: Memory can be executed, read, and
written to
These permissions are enforced by the Windows Memory Manager at the
page level. If an application (or process) tries to access memory in a way
that is not allowed, the system raises an access violation.
Critical Windows APIs for Memory Operations
Windows has a few important APIs for memory manipulations. These APIs
are the building blocks of process injection. The ‘Ex’ versions for these
functions are for external processes, whereas the regular successors are
for the memory space of the calling process. Knowing these APIs enables
the detection of potential injection activities and tracking.
VirtualAlloc/VirtualAllocEx: Reserves and commits memory in a
process
VirtualProtect/VirtualProtectEx: Changes memory region
permissions
ReadProcessMemory: Reads data from another process’s memory
space
WriteProcessMemory: Writes data to another process’s memory
space
VirtualFree/VirtualFreeEx: Releases allocated memory regions
Types of Process Injection Techniques
1. DLL Injection
DLL Injection is the process of forcing a process to load a malign DLL files.
It uses a set of API functions: OpenProcess(), VirtualAllocEx(), and
CreateRemoteThread(). This begins with reserving memory inside the
target process to hold the path of the DLL. It then starts a remote thread
that calls LoadLibrary() with the path as a parameter to instruct the target
process to load the malicious DLL.
An injected DLL has full access to the target process functions/processes
with memory addresses of the entire memory space of the target process
and all other modules the target has loaded into memory.
2. Code Injection
Code injection is a form of attack that injects malicious code into a
process memory space, and the code executes upon it. This simply writes
a code to the address of a process memory space. This is a multi-step
technique that includes getting a handle on the process, using
VirtualAllocEx() to allocate memory, WriteProcessMemory() to write the
code, and then finally, CreateRemoteThread() to execute it.
The code that it runs has the permissions of the target process in which it
is executing, and all security privileges and access rights will be inherited.
3. Thread Execution Hijacking
Thread execution hijacking suspends a thread in the target process,
changes its execution context to point to the attacker code, and continues
the execution. In this technique, the attacker makes use of
SuspendThread(), GetThreadContext(), SetThreadContext(), and
ResumeThread() APIs.
Since it uses a legitimate thread, it makes it harder to get detected as the
hijacked thread runs with its existing privileges to execute the malicious
code.
4. APC (asynchronous procedure call) Injection
APC injection queues malicious code to be executed when a thread enters
an alert state. This method enqueues code onto a thread using
QueueUserAPC(). The code injected into the thread is executed when it
processes its APC queue, which usually happens during particular system
calls or wait operations. This method is well suited to threads that
repeatedly visit mutable states.
5. Reflective DLL Injection
The method of reflective DLL injection loads a DLL with the help of a
Windows loader and does not write a file system artifact. It is a custom
DLL with instructions on how to map it and address it in memory. This trick
involves injecting the loader code and DLL into the target process memory
and executing the loader to prepare the DLL. It avoids detection by normal
DLL loading mechanisms and monitoring.
6. Process Hollowing
Process Hollowing is a stealthy injection technique where attackers create
a legitimate process in a suspended state (using CreateProcess with
CREATE_SUSPENDED), unmap its original memory space (via
NtUnmapViewOfSection/ZwUnmapViewOfSection), allocate new memory
(VirtualAllocEx), write malicious code (WriteProcessMemory), fix the PE
header and relocations, update the Process Environment Block (PEB), and
finally redirect the entry point (SetThreadContext) before resuming
execution (ResumeThread). This allows malicious code to execute under a
legitimate process’s identity and privileges.
How Process Injection Works?
Process injections follow a series of steps in the attempt to execute code
in a target process. No matter the injection method, technical
implementation follows certain steps that manipulate process memory
and change how the process flow executes.
The first one is target process identification and access acquisition
operations. The malicious process uses OpenProcess() to get a handle on
the target process. Required access rights for this handle are
PROCESS_CREATE_THREAD, PROCESS_QUERY_INFORMATION,
PROCESS_VM_OPERATION, PROCESS_VM_WRITE, and PROCESS_VM_READ.
The second crucial step is memory allocation in the target process. The
VirtualAllocEx() allocates memory space in the target process address
space by reserving and committing pages of the virtual memory.
The third step is to copy the shellcode to the allocated memory area.
WriteProcessMemory() copies the code bytes from the source buffer to the
target process memory region. This operation should consider the
alignment and size requirements.
The last step of execution triggering represents the final core components.
Each technique employs one mechanism or another:
CreateRemoteThread() creates a new thread to execute the injected
code
QueueUserAPC() queues code execution in an existing thread
SetThreadContext() modifies existing thread execution flow
Direct modification of function pointers or hooks
Once execution is in motion, the injected code executes inside the context
of the target process, having access to the target process’s resources and
security token. This code can then do whatever it was designed to do,
running under the target process’s privileges and trust level.
How to Detect Process Injection Attacks?
Process injection is difficult to detect because it involves several
components and behaviors of the system. To identify injection activity,
security systems must monitor memory movements, API calls, and all
process behavior.
These detection methods, in combination, form an overall detection
strategy.
Memory Pattern Analysis
Memory analysis is focused on searching for popular patterns in memory
regions of processes. This happens because these regions of the process
memory are scanned by security tools to check the permission settings of
process memory and the expected content. This includes detecting
anomalous executable regions and pages that do not conform to their
typical content signatures within processes, among others.
Memory scanners look for deviations from original process binaries, either
by monitoring changes in normally static process memory structures or
looking for dynamic code segments.
API Call Monitoring
Suspicious sequences of memory manipulation calls are detected by
Windows API monitoring. Security tools monitor OpenProcess() for process
access, VirtualAllocEx() for memory allocation, and WriteProcessMemory()
for memory writes. If a thread is created or manipulated, e.g.,
CreateRemoteThread(), this will be a clear sign of injection.
Changes to state for processes and threads via APIs like SuspendThread()
and SetThreadContext() should also be monitored, as these are often
found in injection chains.
Behavioral Indicators
Monitoring the behavior of processes is done to identify unexpected
patterns of activity suggesting these injection attempts. Intrusion
detection systems watch for threads in a relatively stable running process
and changes in the process memory map to keep track of such processes.
These behaviors, along with modification of the Import Address Tables and
cross-process memory operations, are relevant indicators for detection.
Detection Tools
Spotting process injection needs some security tools with deep monitoring
capabilities. Real-time analysis is done by process monitors that monitor
API calls and system actions, while memory analysis tools perform a deep
analysis of the process memory spaces. Event log analyzers allow teams
to record the history of security events within the system so that they can
gain a perspective on the past.
Enterprise detection and response (EDR) solution such
as SentinelOne combines various ways to monitor with analytic
capabilities. There are system administration tools such as process
monitor and process explorer, which show the processes in detail as well
as the memory allocation per process.
How to Prevent Process Injection Attacks?
Prevention for process injection cannot be provided by a single security
control but involves controls at the system, process, and code levels.
These mitigations focus on limiting process injection capabilities, as well
as making potential target processes harder to inject into.
System-Level Prevention
Preventative measures at the system level begin with the correct
management of access and privileges. Systems should have process
creation and manipulation rights configured to restrict non-administrative
users such that they can only open handles to sensitive processes on
systems. These restrictions are enforced by user account control (UAC)
and AppLocker policies to manage which processes can run and at what
privilege level.
Code Signing
Another important layer of prevention is code signing enforcement.
Modules should be loaded with their digital signatures verified, and
inappropriately signed or unsigned codes should be rejected by the
systems. Windows Defender Application Control (WDAC) policies enforce
code integrity requirements and disable the loading of unsigned DLLs and
executables.
Memory Protection
Memory protection mechanisms that are an important part of the defense.
Data Execution Prevention (DEP) protects against code execution from
data pages, whereas Address Space Layout Randomization (ASLR) makes
it difficult to target specific memory.
Medium protected-process mitigations include Control Flow Guard (CFG),
which checks targets for indirect calls, and Protected Process Light (PPL,)
which limits the ability of processes to open existing ones according to
member signature levels.
Application Hardening
Even for application hardening, the security team needs to follow secure
coding practices and compiler options as well. Developers should
configure security features, such as /DYNAMICBASE and /NXCOMPAT,
implement exception handling, and validate memory operations within the
application debugging process.
Elevate your security posture with real-time detection, machine-speed
response, and total visibility of your entire digital environment.
Conclusion
Process injection injects malicious code into memory spaces alongside
other ongoing processes. The attacker forces target processes to execute
arbitrary code, plus they write their own code into address spaces. The
reason why it’s so dangerous is that it can evade traditional threat
detection techniques. You need to use advanced security solutions and
prevention strategies to catch it.
These include memory protection, behavioral controls, access controls,
and other things. Understanding the mechanics of process injection
techniques enables organizations to harden their systems appropriately
and deploy security controls more effectively.