T1055.009
Process Injection: Proc Memory
Description from ATT&CK
Adversaries may inject malicious code into processes via the /proc filesystem in order to evade process-based defenses as well as possibly elevate privileges. Proc memory injection is a method of executing arbitrary code in the address space of a separate live process.
Proc memory injection involves enumerating the memory of a process via the /proc filesystem (
/proc/[pid]) then crafting a return-oriented programming (ROP) payload with available gadgets/instructions. Each running process has its own directory, which includes memory mappings. Proc memory injection is commonly performed by overwriting the target processes’ stack using memory mappings provided by the /proc filesystem. This information can be used to enumerate offsets (including the stack) and gadgets (or instructions within the program that can be used to build a malicious payload) otherwise hidden by process memory protections such as address space layout randomization (ASLR). Once enumerated, the target processes’ memory map within/proc/[pid]/mapscan be overwritten using dd.(Citation: Uninformed Needle)(Citation: GDS Linux Injection)(Citation: DD Man)Other techniques such as Dynamic Linker Hijacking may be used to populate a target process with more available gadgets. Similar to Process Hollowing, proc memory injection may target child processes (such as a backgrounded copy of sleep).(Citation: GDS Linux Injection)
Running code in the context of another process may allow access to the process's memory, system/network resources, and possibly elevated privileges. Execution via proc memory injection may also evade detection from security products since the execution is masked under a legitimate process.
Atomic Tests
- Atomic Test #1: Inplace Instruction Overwrite
- Atomic Test #2: Instruction Overwrite Jump
- Atomic Test #3: GOT Injection
- Atomic Test #4: Return Address Overwrite
- Atomic Test #5: ROP chain Mprotect Return Address Overwrite
- Atomic Test #6: Return Address Overwrite for full ROP chain execution
Atomic Test #1: Inplace Instruction Overwrite
This technique implements a Direct Instruction Overwrite. Bypassing the need to look for a separate Code Cave, It locates the exact memory address the CPU is about to execute (via the RIP register, gathered in the /proc/PID/syscall file) and overwrites that location with the entire shellcode in /proc/PID/mem.
The injection targets RIP - 2 to account for Linux kernel syscall restarting: when a process interrupted during a system call is resumed, the kernel typically rewinds the instruction pointer by 2 bytes to re-execute the syscall instruction. To prevent crashes in cases where the process was not in a syscall, a NOP sled (padding with 0x90) is prepended to the payload, ensuring the execution flow safely slides into the shellcode regardless of the exact byte offset. [!]: Strictly speaking, this technique does not require handling syscall restarts, since we are not interrupting the victim during a syscall. The NOP sled is included for generality (the same shellcode could be reused in scenarios where syscall restarting does occur) and as a defensive measure against off-by-a-few-bytes inaccuracies in the RIP read from /proc//syscall.
Note: this test forks a child process to use as the injection target. This allows the test to run on systems where ptrace_scope=1 (default on most Linux distributions), where a process can only modify the memory of its own descendants. This may differ from a real-world scenario where the attacker targets an arbitrary process, but for the purpose of this test it preserves the detection-relevant behavior: the same syscalls and /proc//mem access patterns are generated regardless of the relationship between injector and target.
Supported Platforms: Linux
auto_generated_guid: 50859b3b-b088-4c7b-973d-03a0365a9bf9
Inputs
| Name | Description | Type | Default Value |
|---|---|---|---|
| bin_path | path to inplace_instruction_overwrite | path | PathToAtomicsFolder/T1055.009/bin/inplace_instruction_overwrite |
Attack Commands: Run with sh!
#{bin_path}Cleanup Commands
rm -f /tmp/pwnedDependencies: Run with sh!
Description: gcc must be installed
Check Prereq Commands
which gccGet Prereq Commands
apt-get install -y gccDescription: inplace_instruction_overwrite must be compiled
Check Prereq Commands
test -f PathToAtomicsFolder/T1055.009/bin/inplace_instruction_overwriteGet Prereq Commands
make -C PathToAtomicsFolder/T1055.009/srcDescription: /tmp/pwned must not exist before the test
Check Prereq Commands
test ! -f /tmp/pwnedGet Prereq Commands
rm -f /tmp/pwnedAtomic Test #2: Instruction Overwrite Jump
This technique achieves control-flow hijacking via Code Patching. It first identifies a code cave by scanning /proc//maps and writes the shellcode into it through /proc//mem. It then reads the current Instruction Pointer (RIP) to understand exactly what instruction the CPU is about to execute, and overwrites the instructions at that memory location with an unconditional jump pointing to the shellcode address.
The injection targets RIP - 2 to account for Linux kernel syscall restarting: when a process interrupted during a system call is resumed, the kernel typically rewinds the instruction pointer by 2 bytes to re-execute the syscall instruction. To prevent crashes in cases where the process was not in a syscall, a NOP sled (padding with 0x90) is prepended to the payload, ensuring the execution flow safely slides into the shellcode regardless of the exact byte offset. [!]: Strictly speaking, this technique does not require handling syscall restarts, since we are not interrupting the victim during a syscall. The NOP sled is included for generality (the same shellcode could be reused in scenarios where syscall restarting does occur) and as a defensive measure against off-by-a-few-bytes inaccuracies in the RIP read from /proc//syscall.
Note: this test forks a child process to use as the injection target. This allows the test to run on systems where ptrace_scope=1 (default on most Linux distributions), where a process can only modify the memory of its own descendants. This may differ from a real-world scenario where the attacker targets an arbitrary process, but for the purpose of this test it preserves the detection-relevant behavior: the same syscalls and /proc//mem access patterns are generated regardless of the relationship between injector and target.
Supported Platforms: Linux
auto_generated_guid: 3f452c87-25b5-47c0-81d8-01908df1b927
Inputs
| Name | Description | Type | Default Value |
|---|---|---|---|
| bin_path | path to instruction_overwrite_jump | path | PathToAtomicsFolder/T1055.009/bin/instruction_overwrite_jump |
Attack Commands: Run with sh!
#{bin_path}Cleanup Commands
rm -f /tmp/pwnedDependencies: Run with sh!
Description: gcc must be installed
Check Prereq Commands
which gccGet Prereq Commands
apt-get install -y gccDescription: instruction_overwrite_jump must be compiled
Check Prereq Commands
test -f PathToAtomicsFolder/T1055.009/bin/instruction_overwrite_jumpGet Prereq Commands
make -C PathToAtomicsFolder/T1055.009/srcDescription: /tmp/pwned must not exist before the test
Check Prereq Commands
test ! -f /tmp/pwnedGet Prereq Commands
rm -f /tmp/pwnedAtomic Test #3: GOT Injection
This technique identifies a code cave by scanning /proc//maps and writes the shellcode into it through /proc//mem. To redirect the execution flow, it parses the target's ELF structure through /proc//exe to locate the Global Offset Table (.got.plt) and calculates the absolute addresses for PIE-enabled binaries. By overwriting these GOT entries with the shellcode's address, the injector ensures that the next time the victim calls a dynamic library function, it will inadvertently execute the injected payload instead.
get_got: Locates the Global Offset Table (.got.plt or .got), which is an array of pointers the program uses to dynamically find external library functions.
- Finds the string table (shstrtab) containing the names of all sections.
- Searches for the section named ".got.plt", extracting its address and size.
- PIE Handling: If the executable is dynamic (ET_DYN / PIE), the found address is just a relative offset. It must be added to the base_address (found before) to get the absolute RAM address.
Note: this test forks a child process to use as the injection target. This allows the test to run on systems where ptrace_scope=1 (default on most Linux distributions), where a process can only modify the memory of its own descendants. This may differ from a real-world scenario where the attacker targets an arbitrary process, but for the purpose of this test it preserves the detection-relevant behavior: the same syscalls and /proc//mem access patterns are generated regardless of the relationship between injector and target.
Supported Platforms: Linux
auto_generated_guid: 4383bbd3-aa6c-49fd-a1a9-cf112c95982c
Inputs
| Name | Description | Type | Default Value |
|---|---|---|---|
| bin_path | path to got_injection | path | PathToAtomicsFolder/T1055.009/bin/got_injection |
Attack Commands: Run with sh!
#{bin_path}Cleanup Commands
rm -f /tmp/pwnedDependencies: Run with sh!
Description: gcc must be installed
Check Prereq Commands
which gccGet Prereq Commands
apt-get install -y gccDescription: got_injection must be compiled
Check Prereq Commands
test -f PathToAtomicsFolder/T1055.009/bin/got_injectionGet Prereq Commands
make -C PathToAtomicsFolder/T1055.009/srcDescription: /tmp/pwned must not exist before the test
Check Prereq Commands
test ! -f /tmp/pwnedGet Prereq Commands
rm -f /tmp/pwnedAtomic Test #4: Return Address Overwrite
This technique performs control-flow hijacking via Return Address Overwriting. It first identifies a code cave by scanning /proc//maps and writes the shellcode into it through /proc//mem. It then inspects the process stack (from the RSP register) and overwrite every possibile candidate for return address with the location with the address of the code cave, the execution is redirected to the payload the moment the CPU executes the next RET instruction.
Note: this test forks a child process to use as the injection target. This allows the test to run on systems where ptrace_scope=1 (default on most Linux distributions), where a process can only modify the memory of its own descendants. This may differ from a real-world scenario where the attacker targets an arbitrary process, but for the purpose of this test it preserves the detection-relevant behavior: the same syscalls and /proc//mem access patterns are generated regardless of the relationship between injector and target.
Supported Platforms: Linux
auto_generated_guid: 5fabf878-7dd4-48d3-9995-408fac68e166
Inputs
| Name | Description | Type | Default Value |
|---|---|---|---|
| bin_path | path to return_address_overwrite | path | PathToAtomicsFolder/T1055.009/bin/return_address_overwrite |
Attack Commands: Run with sh!
#{bin_path}Cleanup Commands
rm -f /tmp/pwnedDependencies: Run with sh!
Description: gcc must be installed
Check Prereq Commands
which gccGet Prereq Commands
apt-get install -y gccDescription: return_address_overwrite must be compiled
Check Prereq Commands
test -f PathToAtomicsFolder/T1055.009/bin/return_address_overwriteGet Prereq Commands
make -C PathToAtomicsFolder/T1055.009/srcDescription: /tmp/pwned must not exist before the test
Check Prereq Commands
test ! -f /tmp/pwnedGet Prereq Commands
rm -f /tmp/pwnedAtomic Test #5: ROP chain Mprotect Return Address Overwrite
This technique performs control-flow hijacking via Targeted Stack Pivoting and Return Address Overwriting. It first identifies a safe, zero-filled writable (rw-) memory region (a "Zero Cave") by scanning /proc//maps and /proc//mem to avoid corrupting vital process data. It writes the shellcode into this cave and immediately follows it with a dynamically constructed ROP chain, effectively creating a "Fake Stack". This ROP chain is built to invoke mprotect (granting execution permissions) and dynamically adapts to modern glibc constraints by padding multi-pop 'rdx' gadgets with dummy values.
After setting up the Fake Stack, it inspects the process stack (from the RSP register) to locate potential saved return addresses. Instead of writing the full ROP chain directly onto the target's stack, it overwrites these candidates with a minimal 16-byte "Trampoline" consisting of a stack pivot gadget (pop rsp; ret) and the address of the Fake Stack. The moment the CPU executes the next RET instruction, the stack pointer is pivoted, execution is safely redirected into the ROP chain, and from there to the payload.
Compared to a standard "ROP chain + return address overwrite" variant, this pivoting technique prevents catastrophic stack corruption caused by overlapping payloads when multiple return addresses are clustered together. Furthermore, by writing into a verified Zero Cave instead of arbitrary writable memory, it guarantees that no active program variables are destroyed before the payload triggers. This makes the injection highly reliable, stealthy, and capable of bypassing NX/DEP protections without risking immediate segmentation faults.
Note: this test forks a child process to use as the injection target. This allows the test to run on systems where ptrace_scope=1 (default on most Linux distributions), where a process can only modify the memory of its own descendants. This may differ from a real-world scenario where the attacker targets an arbitrary process, but for the purpose of this test it preserves the detection-relevant behavior: the same syscalls and /proc//mem access patterns are generated regardless of the relationship between injector and target.
Supported Platforms: Linux
auto_generated_guid: 3d9e332e-60c9-407a-af4c-a9ae43c4f1d0
Inputs
| Name | Description | Type | Default Value |
|---|---|---|---|
| bin_path | path to rop_mprotect_return_address_overwrite | path | PathToAtomicsFolder/T1055.009/bin/rop_mprotect_return_address_overwrite |
Attack Commands: Run with sh!
#{bin_path}Cleanup Commands
rm -f /tmp/pwnedDependencies: Run with sh!
Description: gcc must be installed
Check Prereq Commands
which gccGet Prereq Commands
apt-get install -y gccDescription: rop_mprotect_return_address_overwrite must be compiled
Check Prereq Commands
test -f PathToAtomicsFolder/T1055.009/bin/rop_mprotect_return_address_overwriteGet Prereq Commands
make -C PathToAtomicsFolder/T1055.009/srcDescription: /tmp/pwned must not exist before the test
Check Prereq Commands
test ! -f /tmp/pwnedGet Prereq Commands
rm -f /tmp/pwnedAtomic Test #6: Return Address Overwrite for full ROP chain execution
The injector reads the victim's RSP register from /proc//syscall and
builds a ROP chain that serializes an argv vector for execve into a
writable memory region, then issues execve to spawn an arbitrary command
with arguments (it doesn't support shell metacharacters e.g. '|', '>' or '>>').
Instead of overwriting a single return address with the full ROP chain
(which risks catastrophic stack corruption when multiple return addresses
are clustered), the chain is placed into a separate zero-filled writable
region - the "Fake Stack". The injector then scans the victim's stack and
overwrites every executable-looking pointer (potential saved return
address) with a minimal 16-byte trampoline: { pivot_gadget, fake_stack_addr }
where pivot_gadget is a pop rsp; ret sequence.
The moment the CPU executes any of the overwritten 'ret' instructions, the
stack pointer is pivoted to the fake stack and the execve ROP chain runs.
The chain dynamically adapts to modern glibc constraints by selecting the
best available pop rdx variant (single or multi-pop) and padding it with
dummy values where required.
Note: this test forks a child process to use as the injection target. This allows the test to run on systems where ptrace_scope=1 (default on most Linux distributions), where a process can only modify the memory of its own descendants. This may differ from a real-world scenario where the attacker targets an arbitrary process, but for the purpose of this test it preserves the detection-relevant behavior: the same syscalls and /proc//mem access patterns are generated regardless of the relationship between injector and target.
Supported Platforms: Linux
auto_generated_guid: 5696f417-30e5-4942-988d-0b9dcfe3a929
Inputs
| Name | Description | Type | Default Value |
|---|---|---|---|
| bin_path | path to return_address_overwrite_fullROPchain | path | PathToAtomicsFolder/T1055.009/bin/return_address_overwrite_fullROPchain |
Attack Commands: Run with sh!
#{bin_path}Cleanup Commands
rm -f /tmp/pwnedDependencies: Run with sh!
Description: gcc must be installed
Check Prereq Commands
which gccGet Prereq Commands
apt-get install -y gccDescription: return_address_overwrite_fullROPchain must be compiled
Check Prereq Commands
test -f PathToAtomicsFolder/T1055.009/bin/return_address_overwrite_fullROPchainGet Prereq Commands
make -C PathToAtomicsFolder/T1055.009/srcDescription: /tmp/pwned must not exist before the test
Check Prereq Commands
test ! -f /tmp/pwnedGet Prereq Commands
rm -f /tmp/pwnedAtomic test(s) for this technique last updated: 2026-05-31 06:47:17 UTC