Process Injection Attacks w ROP

Bramwell Brizendine, Shiva Shashank Kusuma

DEF CON 32 Main Stage · Day 1 · Main Stage

Overview

This talk, "Process Injection Attacks w ROP," presented by Dr. Bramwell Brizendine and Shiva Shashank Kusuma at DEF CON 32, delves into advanced techniques for process injection on Windows systems using Return-Oriented Programming (ROP). The speakers introduce a novel approach to shell codeless ROP, where the functionality traditionally provided by custom shellcode is entirely replicated through carefully constructed ROP chains, circumventing the need to introduce new executable code. This methodology offers a sophisticated bypass for Data Execution Prevention (DEP), a fundamental security mechanism.

Watch on YouTube

Visual summary for Process Injection Attacks w ROP by Bramwell Brizendine, Shiva Shashank Kusuma
Visual summary for Process Injection Attacks w ROP by Bramwell Brizendine, Shiva Shashank Kusuma

Key moments

  1. 0:00 Welcome, speakers, and talk agenda overview
  2. 2:15 Defining shellcodeless Return Oriented Programming (ROP)
  3. 3:05 Techniques for shellcodeless ROP: PushAD and Sniper
  4. 4:10 Methodology for chaining multiple APIs using ROP
  5. 5:45 Generic ROP for process injection: AdjustTokenPrivileges example
  6. 7:00 Novel concept: building Enumerate Processes purely via ROP
  7. 7:45 Conclusion and introduction to the Rop Rocket tool

Process Injection Attacks w ROP

Speakers: Dr. Bramwell Brizendine, Director, Verona Lab; Shiva Shashank Kusuma, Research Assistant

Conference: DEF CON 32

YouTube: https://www.youtube.com/watch?v=1Hx-PzyGtX0

Overview

This talk, "Process Injection Attacks w ROP," presented by Dr. Bramwell Brizendine and Shiva Shashank Kusuma at DEF CON 32, delves into advanced techniques for process injection on Windows systems using Return-Oriented Programming (ROP). The speakers introduce a novel approach to shell codeless ROP, where the functionality traditionally provided by custom shellcode is entirely replicated through carefully constructed ROP chains, circumventing the need to introduce new executable code. This methodology offers a sophisticated bypass for Data Execution Prevention (DEP), a fundamental security mechanism.

The research presented is significant because it moves beyond the typical limitations of shell codeless ROP on Windows, which often involves chaining only a handful of API calls. Brizendine and Kusuma demonstrate the capability to chain "vastly more" Windows and native APIs, enabling complex operations like building an EnumerateProcesses function purely via ROP. This work is not confined to a single vulnerable binary but aims to provide a broad, applicable methodology for leveraging ROP from a compromised binary, offering a powerful toolkit for offensive security researchers and a critical area of study for defenders.

The talk highlights a practical, extendable framework for ROP-based process injection, emphasizing the discovery of generic patterns for API invocation. By focusing on how an attacker, having already compromised a binary, can orchestrate intricate system interactions without deploying traditional shellcode, the speakers shed light on a stealthier and more resilient class of attacks. This research is crucial for understanding the evolving landscape of exploitation techniques and developing more robust defensive strategies against advanced persistent threats.

Background

▶ Watch: Welcome, speakers, and talk agenda overview (0:00)

The concept of Return-Oriented Programming (ROP) emerged as a powerful exploitation technique designed to bypass Data Execution Prevention (DEP). DEP prevents code execution from non-executable memory regions, making traditional shellcode injection difficult. ROP circumvents this by chaining together small, existing instruction sequences (known as gadgets) found within the legitimate code of a program or its loaded libraries. Each gadget typically ends with a RET instruction, which pops the next address off the stack, allowing an attacker to control the program's execution flow by populating the stack with a sequence of gadget addresses.

While ROP is well-established for achieving arbitrary code execution or bypassing DEP to execute injected shellcode, the idea of shell codeless ROP takes this a step further. Instead of using ROP to enable the execution of new code, shell codeless ROP uses ROP chains to directly invoke and chain together existing system functionalities, particularly Windows APIs, to achieve the attacker's objectives without ever introducing custom executable shellcode. This approach is significantly stealthier and harder to detect, as it relies entirely on the legitimate code paths of the operating system and the compromised application.

Historically, shell codeless ROP on Windows has been challenging, often limited to chaining only two or three API calls due to the complexity of setting up call frames and managing parameters entirely through ROP gadgets. This limitation restricted the practical application of such techniques for more complex tasks like process injection. Dr. Brizendine and his team, through prior work like "Jop Rocket" and "Rop Rocket" (which deal with Jump-Oriented Programming and Return-Oriented Programming, respectively), "Shellwasp" (for utilizing Windows syscalls in shellcode), and the NSA-funded "Sherm" (for shellcode analysis), have been at the forefront of exploring these advanced exploitation methodologies. This current research builds upon that foundation, specifically addressing the gap in performing extensive API chaining for shell codeless ROP on Windows.

The motivation for this research stems from the desire to create broadly applicable techniques. The experiments were conducted on a "contrived binary"—an intentionally vulnerable application rich with convenient gadgets—to ensure that the discovered patterns and methodologies are not specific to a single vulnerability or program. This allows the researchers to explore the full potential of ROP for various scenarios, focusing on the practicalities of leveraging ROP once a binary has been compromised, rather than integrating it into custom malware development. The goal is to provide a comprehensive methodology for offensive security, enabling complex operations purely through the orchestration of existing code.

Key Findings

▶ Watch: Techniques for shellcodeless ROP: PushAD and Sniper (3:05)

The central discovery of this research is the development of a robust methodology for shell codeless ROP that enables the chaining of "vastly more" Windows and native APIs than previously demonstrated in the Windows ecosystem. This significantly expands the practical utility of ROP for complex tasks like process injection, moving beyond simple DEP bypasses to full-fledged functional replication. The speakers emphasize the importance of finding unique patterns for API invocation, ensuring that their techniques are broadly applicable across different binaries rather than being tied to specific vulnerabilities.

A core finding is the systematic approach to API chaining. The researchers demonstrated how the return value from one API call, such as the handle or base address obtained from OpenProcess, can be seamlessly used as a parameter for subsequent API calls. For instance, the base address of Ntdll (a critical Windows native API library) can be obtained via ROP and then utilized to resolve other native function addresses required for advanced operations. This inter-API communication, orchestrated entirely through ROP gadgets, forms the backbone of their advanced process injection capabilities.

To precisely control register values and populate the stack with necessary parameters for API calls, the research highlights two critical techniques:

  1. pushad: This technique involves populating general-purpose registers with specific values, which are then pushed onto the stack in a predefined order. This can be efficient if the required values can be staged in registers prior to a pushad gadget.
  2. move dereference (or the "sniper technique"): This method allows for more granular control, enabling attackers to precisely write values to specific locations on the stack. This implies leveraging ROP gadgets that perform MOV [REG], REG or similar operations, followed by incrementing or decrementing pointers to target subsequent stack slots. This precision is crucial for constructing complex data structures and argument lists required by many Windows APIs.

Furthermore, a highly novel contribution is the concept of building an entirely new, functional EnumerateProcesses function purely via ROP. This demonstrates the capability of their methodology to reconstruct high-level operating system functionalities from low-level ROP primitives. This particular finding underscores the power and flexibility of their shell codeless ROP approach, proving it can go beyond merely calling existing functions to synthesizing new ones from existing components. This ROP-based EnumerateProcesses function is also highlighted as being "extendable to other process injection techniques," indicating its foundational role in their broader methodology.

Technical Deep Dive

▶ Watch: Methodology for chaining multiple APIs using ROP (4:10)

The technical core of this research revolves around orchestrating complex system interactions using Return-Oriented Programming (ROP) without introducing any custom executable code. This shell codeless ROP approach fundamentally bypasses Data Execution Prevention (DEP) by exclusively utilizing existing, legitimate instruction sequences (gadgets) within the target process's memory space. The goal is to perform process injection, which typically involves gaining a handle to a target process, allocating memory within it, writing malicious code to that memory, and then causing the target process to execute it. In this shell codeless paradigm, the "malicious code" itself is replaced by ROP chains.

The process begins by identifying a suitable vulnerability (e.g., a buffer overflow) that allows an attacker to control the stack and, consequently, the instruction pointer (EIP/RIP). Once control is gained, the attacker populates the stack with a meticulously crafted sequence of addresses, each pointing to a ROP gadget. These gadgets are small sequences of instructions (e.g., POP EAX; RET, MOV [EAX], EBX; RET, CALL DWORD PTR [ESP+0x10]; RET) that perform specific, atomic operations. By chaining these gadgets, complex operations can be performed.

A critical challenge in shell codeless ROP for process injection is the need to invoke numerous Windows APIs with specific parameters. The speakers highlighted two primary methods for managing register and stack state:

  1. pushad: This instruction pushes all general-purpose 32-bit registers (EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI) onto the stack. While pushad is less common in 64-bit ROP, its 32-bit counterpart is useful for rapidly populating the stack with a set of known values residing in registers. The attacker would first find gadgets to load desired parameter values into specific registers, then execute a pushad gadget, followed by a gadget that calls the target API, expecting its arguments to be on the stack in the order pushad places them. This requires careful alignment and pre-staging of values.
  1. move dereference (the "sniper technique"): This method offers greater precision. It involves finding gadgets that allow an attacker to write arbitrary values to arbitrary memory locations. For example, a gadget sequence like POP EAX; POP EBX; MOV [EAX], EBX; RET would allow writing the value in EBX to the address in EAX. By chaining such gadgets, an attacker can construct complex data structures on the stack or in allocated memory, which are then passed as arguments to API calls. The "increment or decrement to the next slot" aspect refers to using pointer arithmetic gadgets (e.g., ADD EAX, 4; RET) to move a pointer to the next argument slot on the stack or in a structure.

A concrete example of a necessary step in process injection is elevating privileges. The talk specifically mentions using AdjustTokenPrivileges to enable SE_DEBUG_PRIVILEGE. This is crucial because many process injection techniques require debugging privileges to open handles to other processes (e.g., OpenProcess with PROCESS_ALL_ACCESS), allocate memory in them (VirtualAllocEx), write to them (WriteProcessMemory), or create remote threads (CreateRemoteThread).

The ROP chain for AdjustTokenPrivileges would involve:

  • Obtaining the current process token (e.g., via OpenProcessToken).
  • Constructing a TOKEN_PRIVILEGES structure, which defines the privileges to be enabled or disabled. This structure specifies an array of LUID_AND_ATTRIBUTES structures. For SE_DEBUG_PRIVILEGE, the LUID (Locally Unique Identifier) would need to be looked up (e.g., via LookupPrivilegeValue) and the Attributes field set to SE_PRIVILEGE_ENABLED.
  • Setting the DisableAllPrivileges parameter to FALSE to ensure that only the privileges specified in the NewState structure are modified.
  • Finally, calling AdjustTokenPrivileges with the appropriate parameters, all arranged on the stack or in registers using the pushad or move dereference techniques. The speakers specifically show a ROP snippet that provides LPParameter and its address, followed by pushad, indicating how these values are prepared for the API call.

Another critical capability highlighted is the ability to obtain the base address of Ntdll.dll. This is vital because Ntdll.dll contains many low-level, native Windows API functions that are often not directly exposed through kernel32.dll or user32.dll but are essential for advanced system manipulation. By locating Ntdll's base address via ROP, an attacker can then resolve the addresses of specific functions within it (e.g., NtAllocateVirtualMemory, NtWriteVirtualMemory, NtCreateThreadEx) using techniques like parsing the PEB (Process Environment Block) and its LDR (Loader Data) structures, all through ROP. The talk mentions that a return value, such as the base address of Ntdll, can be provided in EAX and then used in subsequent ROP patterns, illustrating the dynamic nature of their chaining methodology.

The ultimate goal of building a new EnumerateProcesses function purely via ROP exemplifies the sophisticated control achieved. This would likely involve ROP chains to:

  1. Call NtQuerySystemInformation with SystemProcessInformation class to get a list of all running processes.
  2. Allocate memory to store the output (e.g., via NtAllocateVirtualMemory).
  3. Parse the SYSTEM_PROCESS_INFORMATION structure returned by NtQuerySystemInformation to extract process IDs, names, and other relevant details, again using ROP gadgets for memory dereferencing and arithmetic.

This level of functional reconstruction demonstrates a profound command over the system's underlying mechanisms, all without injecting a single byte of traditional shellcode.

Demo / Proof of Concept

▶ Watch: Novel concept: building Enumerate Processes purely via ROP (7:00)

The talk included a demonstration of the developed shell codeless ROP techniques for process injection. The speakers explicitly mentioned presenting "a sample process injection technique that has a highly novel solution to a rather significant problem." While the exact visual details of the demo are not described in the transcript, the context suggests it showcased the culmination of their research: building a functional component purely through ROP chains.

Specifically, the demonstration likely focused on the novel concept of constructing an EnumerateProcesses function entirely via ROP. This would involve orchestrating a series of Windows API calls, such as NtQuerySystemInformation, memory allocation, and subsequent parsing of the returned data, all without traditional shellcode. The demo would have illustrated how the ROP chains, utilizing techniques like pushad and move dereference, successfully manipulated the program's execution flow to perform these complex operations, ultimately listing active processes. This proof of concept was conducted on a "contrived binary," an intentionally vulnerable application with convenient gadgets, to emphasize the broad applicability of their methodology rather than its exploitability against a specific, real-world vulnerability.

Defensive Implications

▶ Watch: Conclusion and introduction to the Rop Rocket tool (7:45)

The advanced shell codeless ROP techniques presented in this talk pose significant challenges for traditional defensive measures. Since no new executable code (shellcode) is ever introduced into memory, Data Execution Prevention (DEP) is entirely bypassed by design, rendering it ineffective against this class of attacks. Defenders must shift their focus from detecting unauthorized code execution to identifying anomalous control flow and unusual sequences of legitimate API calls.

Key defensive implications and mitigation strategies include:

  1. Advanced Control Flow Integrity (CFI): Traditional CFI solutions might struggle here as ROP reuses legitimate code paths. However, more advanced CFI implementations that can analyze the semantics of ROP chains or detect excessively long and complex ROP chains, especially those crossing module boundaries or involving unusual gadget sequences, could offer some protection. Monitoring indirect calls and returns for deviations from expected program behavior is critical.
  1. API Call Monitoring and Anomaly Detection: Security solutions should focus on monitoring the sequence and context of Windows API calls. For instance, the activation of SE_DEBUG_PRIVILEGE via AdjustTokenPrivileges is a highly suspicious event if it occurs in an application that typically doesn't require such elevated permissions. Similarly, an application suddenly calling OpenProcess, VirtualAllocEx, WriteProcessMemory, and CreateRemoteThread in quick succession, especially targeting another process, should trigger high-severity alerts. Behavior-based detection systems that baseline normal application behavior and flag deviations are essential.
  1. Enhanced Address Space Layout Randomization (ASLR): While ASLR makes finding specific gadgets harder, it's not a complete defense. High-entropy ASLR, combined with technologies like Mandatory ASLR (forcing all modules to be randomized), can increase the difficulty for attackers to reliably build ROP chains. However, information leaks (e.g., through format string bugs or uninitialized memory disclosures) can often negate ASLR.
  1. Exploit Mitigation Technologies (EMET/Windows Defender Exploit Guard): Features like ROP Gadget Protection or Export Address Filtering (EAF) in Microsoft's Exploit Guard attempt to detect ROP by monitoring calls to exported functions from unexpected locations or detecting common ROP patterns (e.g., POP RDI; RET). While these can be effective against known ROP patterns, sophisticated shell codeless ROP may use less common gadgets or dynamically resolve functions, potentially evading simpler detection.
  1. Heap and Stack Protections: Stronger compiler-based protections like Stack Canaries (or Stack Cookies) and SafeSEH (Structured Exception Handling protection) are crucial for preventing the initial memory corruption vulnerabilities that enable ROP in the first place. If attackers cannot hijack control flow, ROP chains cannot be executed.
  1. Granular Privilege Management: Enforcing the principle of least privilege for all applications, users, and services can limit the impact of a successful ROP attack. If a compromised application runs with minimal privileges, even a successful ROP chain might not be able to elevate privileges or perform sensitive actions on other processes.
  1. Threat Intelligence and Research: Defenders must stay abreast of the latest ROP techniques and gadget discovery methodologies. Understanding how attackers find and chain gadgets, particularly for Windows APIs, is crucial for developing proactive detection and prevention mechanisms. This includes analyzing public research like the work presented by Dr. Brizendine and Shiva Shashank Kusuma.

In essence, the shift towards shell codeless ROP necessitates a defensive paradigm that moves beyond signature-based detection and simple DEP bypass checks, focusing instead on deep behavioral analysis, control flow integrity, and comprehensive API call monitoring.

Key Takeaways

  • Shell Codeless ROP as an Advanced DEP Bypass: The research demonstrates a sophisticated method for bypassing Data Execution Prevention (DEP) by entirely replacing traditional shellcode with Return-Oriented Programming (ROP) chains, leveraging existing code within the compromised process.
  • Extensive API Chaining on Windows: A significant contribution is the proven methodology for chaining "vastly more" Windows and native APIs (e.g., from Ntdll.dll) using ROP gadgets, enabling complex operations like process injection that were previously difficult to achieve without custom shellcode.
  • Precision in ROP Chain Construction: Critical techniques like pushad for rapid register-to-stack transfers and move dereference (the "sniper technique") for precise value placement on the stack are fundamental to constructing complex API call arguments and data structures.
  • Novel ROP-based Functional Reconstruction: The ability to build a new, functional EnumerateProcesses function purely via ROP highlights the power of this methodology to reconstruct high-level operating system functionalities from low-level ROP primitives, demonstrating its extendability to other process injection techniques.
  • Importance of Privilege Elevation: The talk underscores the necessity of orchestrating AdjustTokenPrivileges via ROP, specifically to enable SE_DEBUG_PRIVILEGE, as a prerequisite for many advanced process injection operations.
  • Broad Applicability of Methodology: The research focuses on discovering generic ROP patterns applicable to many binaries, rather than specific vulnerabilities, providing a robust and versatile framework for offensive security once a binary is compromised.

About the Speaker(s)

Dr. Bramwell Brizendine is the Director of the Verona Lab, where he focuses on vulnerability research. He holds a PhD in Cyber Operations, a highly technical degree, and serves as an Assistant Professor of Cybersecurity. Dr. Brizendine is a prolific creator in the field of offensive security, having developed the Shellwasp tool, which facilitates the use of Windows System Calls in shellcode. He is also the creator of Jop Rocket and Rop Rocket, tools specifically designed for Return-Oriented Programming and Jump-Oriented Programming. Additionally, he led an NSA-funded research project called Sherm, dedicated to analyzing shellcode. Dr. Brizendine is a seasoned speaker, having presented at numerous conferences, including previous DEF CON events where his earlier projects were showcased.

Shiva Shashank Kusuma is a Research Assistant who collaborated with Dr. Brizendine on this project. He holds a Master's degree in Computer Science and is currently pursuing a second Master's degree in Cyber Security. Shiva is actively seeking internship opportunities, indicating his dedication to advancing his practical experience in the field of cybersecurity research.

Reviews

Dr. Zero (Offensive Security Researcher) — MUST SEE

This talk presents a truly groundbreaking advancement in Return-Oriented Programming, demonstrating how to achieve complex process injection on Windows entirely without traditional shellcode. Dr. Brizendine and his team have developed a systematic methodology for chaining "vastly more" Windows and native APIs using ROP, even reconstructing high-level functions like EnumerateProcesses from low-level primitives. This is not just a DEP bypass; it's a blueprint for stealthier, more resilient advanced persistent threats, demanding a significant re-evaluation of defensive strategies.

Heather Calloway (CISO) — STRONG ACCEPT

This research demonstrates a highly sophisticated and stealthy method for process injection using shell codeless ROP, effectively rendering traditional Data Execution Prevention (DEP) irrelevant against such attacks. The ability to chain numerous Windows APIs for complex operations, including the reconstruction of functions like EnumerateProcesses, signifies a critical shift in the threat landscape. For security leaders, this work underscores the urgent need to evolve defensive strategies from simple execution prevention to advanced behavioral monitoring and control flow integrity, recognizing that the very tools of the operating system can be weaponized without introducing new code.

→ Top-rated talks at DEF CON 32 Main Stage

All talks from DEF CON 32 Main Stage