ArticlePublisher preview available

Pure-Call Oriented Programming (PCOP): chaining the gadgets using call instructions

Authors:
To read the full-text of this research, you can request a copy directly from the authors.

Abstract and Figures

Return-oriented programming (ROP) and jump-oriented programming (JOP) are two well-known code-reuse attacks in which short code sequences ending in ret or jmp instructions are located and chained in a specific order to execute the attacker’s desired payload. JOP, comparing to ROP, is even more effective because it can be invoked without any reliance on the ret instruction and therefore it can bypass new defense mechanisms against ROP. In this paper, we continue this line of work by proposing Pure-Call Oriented Programming (PCOP). In PCOP, we drive the control flow by proposing special gadgets that all end in a call instruction rather than ret or jmp. We then propose techniques for chaining gadgets that removes the side-effects arise from the call-ending gadgets. The idea of having call-ending gadgets with the term Call Oriented Programming has been noted in some previous work but using call gadgets in these works, due to side-effects of the call instruction, was limited to one or two call-ending gadgets between other ret/jmp gadgets. Our work is the first that shows real code-reuse attacks solely based on call gadgets. We also show that our proposed approach is Turing-complete, meaning that any functionality can be driven by PCOP. We have successfully identified some call-oriented gadgets inside GNU libc library. Our experiments with the example shellcode show the practicality of the proposed approach. Finally, we propose a variant of PCOP named TinyCOP which resists detection by recent code-reuse defense mechanisms.
This content is subject to copyright. Terms and conditions apply.
J Comput Virol Hack Tech (2018) 14:139–156
https://doi.org/10.1007/s11416-017-0299-1
ORIGINAL PAPER
Pure-Call Oriented Programming (PCOP): chaining the gadgets
using call instructions
AliAkbar Sadeghi1·Salman Niksefat1·Maryam Rostamipour1
Received: 27 January 2017 / Accepted: 26 April 2017 / Published online: 15 May 2017
© Springer-Verlag France 2017
Abstract Return-oriented programming (ROP) and jump-
oriented programming (JOP) are two well-known code-reuse
attacks in which short code sequences ending in ret or jmp
instructions are located and chained in a specific order to
execute the attacker’s desired payload. JOP, comparing to
ROP, is even more effective because it can be invoked with-
out any reliance on the ret instruction and therefore it can
bypass new defense mechanisms against ROP. In this paper,
we continue this line of work by proposing Pure-Call Ori-
ented Programming (PCOP). In PCOP, we drive the control
flow by proposing special gadgets that all end in a call instruc-
tion rather than ret or jmp. We then propose techniques for
chaining gadgets that removes the side-effects arise from the
call-ending gadgets. The idea of having call-ending gadgets
with the term Call Oriented Programming has been noted in
some previous work but using call gadgets in these works,
due to side-effects of the call instruction, was limited to
one or two call-ending gadgets between other ret/jmp gad-
gets. Our work is the first that shows real code-reuse attacks
solely based on call gadgets. We also show that our proposed
approach is Turing-complete, meaning that any functionality
can be driven by PCOP. We have successfully identified some
call-oriented gadgets inside GNU libc library. Our experi-
This work is supported by APA research center (http://apa.aut.ac.ir)at
Amirkabir University of Technology, Tehran, Iran.
BSalman Niksefat
niksefat@aut.ac.ir
AliAkbar Sadeghi
aliakbar.sadeghi@aut.ac.ir
Maryam Rostamipour
rostamipoor@aut.ac.ir
1APA Research Center, Amirkabir University of Technology,
No. 424, Hafez Ave, Tehran, Iran
ments with the example shellcode show the practicality of the
proposed approach. Finally, we propose a variant of PCOP
named TinyCOP which resists detection by recent code-reuse
defense mechanisms.
Keywords Code-reuse attack ·Pure-Call Oriented Pro-
gramming ·Return oriented programming ·Jump oriented
programming ·Exploitation
1 Introduction
In this paper, we propose new techniques for code-reuse
attacks. The main idea in code-reuse attacks is to use existing
code in a process address space to execute arbitrary payloads.
This is a promising approach since it can bypass the write-
xor-execute(WX) defense mechanism against classic code
injection attacks and also makes it harder for intrusion detec-
tion systems to detect such attacks on the network. This is due
to the fact that the payload is not injected from outside and
the attacker uses the existing pieces of code in the memory
to launch the attack.
The basic building blocks in code-reuse attacks are gad-
gets. Gadgets are sequence of instructions ending in an
instruction that diverts the control flow to the next gadget
or some other structure that is used for chaining the gadgets.
The last instruction of a gadget can be instructions like ret,
jmp or call. In return-oriented-programming (ROP) [14], all
gadgets are ended with the ret whereas in jump-oriented-
programming (JOP) [1,3] the gadgets are ended with jmp
or sometimes call instructions. In JOP, the reliance on the
ret instruction has been removed to bypass detection mecha-
nisms that are sensitive to frequent use of the ret instruction.
In this paper, we argue that the code-reuse attack can be
launched by solely relying on call-ending gadgets. Using of
123
Content courtesy of Springer Nature, terms of use apply. Rights reserved.
... Brizendine & Babcock, 2022) which has led to the creation of a large number of code-reuse attacks and tools such as Call-oriented programming (COP) , Counterfeit Objectoriented Programming (COOP)(El-Zoghby & Azer, 2020), string-oriented programming (SOP) (Payer & Gross, 2013), JIT-ROP (Priyadarshan et al., 2020), Control JuJutsu (Evans et al., 2015), ROP/JOP plus heap spraying (Erdodi, 2015), Functionoriented programming (FOP) (Guo et al., 2018), Pure-call oriented programming(A. Sadeghi et al., 2018), Limbo (Schwartz et al., 2020), PACMAN (Ravichandran et al., 2022), NMT Shellcode (Liguori et al., 2022), loop-oriented programming(LOP), The call-preceded ROP (CPROP), block-oriented programming (BOP) among others. ...
Preprint
Full-text available
Internet security is determined by three types of key actors: attackers, defenders, and software application auditors. Offensive security represents a crucial stage in the development of computer security by trying to detect new attack techniques before malicious actors discover them and execute them in the operational environment. This constitutes a real arms race that is necessary to prevent massive attacks before they happen. This study aims to establish the state of the investigation of jump-oriented programming (JOP), a software exploitation technique, as well as the effective countermeasures that help contain attacks that use this type of techniques. Following the systematic literature mapping approach, a review was carried out in relevant literature databases such as ACM Digital Library, IEEE Digital Library, ISI Web of Science, Proquest One Academic, Science@Direct, Scopus and Springer Link. The results of the research show that much of the research around JOP attempts to develop control and mitigation techniques such as Control-Flow Locking, branch regulation (BR), JITSafe, CIMB of JOP attacks and code-reuse attacks (CRA) while in offensive security it seeks to improve the effectiveness of JOP to overcome existing countermeasures or establish new specific attack scenarios. New techniques derived from the original JOP have been proposed, such as SOP, SROP, COP, COOP, DOOP, or new techniques are being developed in combination with other types of CRA techniques such as heap spraying. The research concludes that JOP is still an interesting attack technique in the area of offensive security, but most of the research has been done in Intel x86 and ARM environments, so these techniques need to be explored in other architectures.
... For intra-function control-flow integrity, specifically, indirect jumps from switch statements, LLVM-the compiler upon which DeTRAP is based-compiles them to use 1 [20], [68], which provides type-based CFI, meeting more than the minimum requirements above (more details in Section V-C). A more finegrained CFI could provide better protection against forwardedge threats, such as call-oriented [59] and function-reuse [36] attacks, but is unnecessary for reverse-edge protection. Forward-CFI can prevent mismatches between function prologues and epilogues for most programs. ...
Preprint
Modern microcontroller software is often written in C/C++ and suffers from control-flow hijacking vulnerabilities. Previous mitigations suffer from high performance and memory overheads and require either the presence of memory protection hardware or sophisticated program analysis in the compiler. This paper presents DeTRAP (Debug Trigger Return Address Protection). DeTRAP utilizes a full implementation of the RISC-V debug hardware specification to provide a write-protected shadow stack for return addresses. Unlike previous work, DeTRAP requires no memory protection hardware and only minor changes to the compiler toolchain. We tested DeTRAP on an FPGA running a 32-bit RISC-V microcontroller core and found average execution time overheads to be between 0.5% and 1.9% on evaluated benchmark suites with code size overheads averaging 7.9% or less.
... It is widely known ROP attacks can achieve Turing-completeness [27]. Jump-(JOP [28]) and call-oriented programming (COP [29,30]) attacks are two other code reuse attacks, which involve tampering forward control-flow transfers, namely indirect jumps and indirect calls respectively, in order to chain sequences of gadgets. ...
Preprint
Full-text available
Control-flow attestation (CFA) unifies the worlds of control-flow integrity and platform attestation by measuring and reporting a target's run-time behaviour to a verifier. Trust assurances in the target are provided by testing whether its execution follows an authorised control-flow path. The problem has been explored in various settings, such as assessing the trustworthiness of cyber-physical systems, Internet of Things devices, cloud platforms, and many others. Despite a significant number of proposals being made in recent years, the area remains fragmented, addressing different adversarial behaviours, verification paradigms, and deployment challenges. In this paper, we present the first survey of control-flow attestation, examining the core ideas and solutions in state-of-the-art schemes. In total, we survey over 30 papers published between 2016-2024, consolidate and compare their key features, and pose several challenges and recommendations for future research in the area.
... Since each gadget itself ends with a function return, more return addresses are popped from the stack which allows it to chain multiple gadgets together, creating the desired behavior. Of course there are also attacks that target other instructions, such as Jump-Oriented Programming [6] for indirect jumps and Call-Oriented Programming [7] for function calls. But countermeasures for these attacks will not be the focus of this paper. ...
... • Indirect calls [37], for example the instruction call rax that calls another function to the address stored in the register rax, and, • Indirect jumps [2], for example the instruction jmp rax which jumps to the address stored in the register rax. ...
Article
Full-text available
Over the years, a popular method to hijack a process flow has been to use Return Oriented Programming gadgets. This method involves chaining together several pieces of code called gadgets to perform malicious actions. A vital part of these approaches is to identify and classify gadgets from the executable to screen the usable ones. To this end, researchers have developed various solutions that are commonly used during vulnerability analysis. However, they require a significant computation time that may limit their utilization. The aim of this paper is to investigate whether machine learning can aid to perform such gadget classifications to allow an analyst to exploit a vulnerability. With this objective, a labeled dataset of gadgets has been created through a time-consuming but high-accuracy symbolic analysis tool. Suitable data transformations and discrete-valued data encodings have been identified for machine learning methods to work effectively on this dataset. Finally, an empirical comparison of the classification models has been performed and it has been possible to identify the Random Forest classifier with the target encoding that produces an ROC-AUC over 0.98. The classifier has also been used to reduce the number of gadgets and significantly decrease the computation time of symbolic tools.
Chapter
In this paper, we combine static code analysis and symbolic execution to bypass Intel’s Control-Flow Enforcement Technology (CET) by exploiting function pointer hijacking. We present Untangle, an open-source tool that implements and automates the discovery of global function pointers in exported library functions and their call sites. Then, it determines the constraints that need to be satisfied to reach those pointers. Our approach manages naive built-in types and complex parameters like structure pointers. We demonstrate the effectiveness of Untangle on 8 of the most used open source C libraries, identifying 57 unique global function pointers, reachable through 1488 different exported functions. Untangle can find and verify the correctness of the constraints for 484 global function pointer calls, which can be used as attack vectors for control-flow hijacking. Finally, we discuss current and future defense mechanisms against control-flow hijacking using global function pointers. KeywordsBinary ExploitationControl-Flow IntegrityControl-Flow HijackingStatic AnalysisSymbolic Execution
Conference Paper
Full-text available
Despite the many efforts made in recent years to mitigate runtime attacks such as stack and heap based buffer overflows, these attacks are still a common security concern in today's computing platforms. Attackers have even found new ways to enforce runtime attacks including use of a technique called return-oriented programming. Trusted Computing provides mechanisms to verify the integrity of all executable content in an operating system. But they only provide integrity at load-time and are not able to prevent or detect runtime attacks. To mitigate return-oriented programming attacks, we propose new runtime integrity monitoring techniques that use tracking instrumentation of program binaries based on taint analysis and dynamic tracing. We also describe how these techniques can be employed in a dynamic integrity measurement architecture (DynIMA). In this way we fill the gap between static load-time and dynamic runtime attestation and, in particular, extend trusted computing techniques to effectively defend against return-oriented programming attacks.
Conference Paper
Full-text available
Modern runtime attacks increasingly make use of the powerful return-oriented programming (ROP) attack techniques and principles such as recent attacks on Apple iPhone and Acrobat products to name some. These attacks even work under the presence of modern memory protection mechanisms such as data execution prevention (DEP). In this paper, we present our tool, ROPdefender, that dynamically detects conventional ROP attacks (that are based on return instructions). In contrast to existing solutions, ROPdefender can be immediately deployed by end-users, since it does not rely on side information (e.g., source code or debugging information) which are rarely provided in practice. Currently, our tool adds a runtime overhead of 2x which is comparable to similar instrumentation-based tools.
Conference Paper
Full-text available
We show that on both the x86 and ARM architectures it is possible to mount return-oriented programming attacks without using return instructions. Our attacks instead make use of certain instruction sequences that behave like a return, which occur with sufficient frequency in large libraries on (x86) Linux and (ARM) Android to allow creation of Turing-complete gadget sets. Because they do not make use of return instructions, our new attacks have negative implications for several recently proposed classes of defense against return-oriented programming: those that detect the too-frequent use of returns in the instruction stream; those that detect violations of the last-in, first-out invariant normally maintained for the return-address stack; and those that modify compilers to produce code that avoids the return instruction.
Article
As existing defenses like ASLR, DEP, and stack cookies are not sufficient to stop determined attackers from exploiting our software, interest in Control Flow Integrity (CFI) is growing. In its ideal form, CFI prevents flows of control that were not intended by the original program, effectively putting a stop to exploitation based on return oriented programming (and many other attacks besides). Two main problems have prevented CFI from being deployed in practice. First, many CFI implementations require source code or debug information that is typically not available for commercial software. Second, in its ideal form, the technique is very expensive. It is for this reason that current research efforts focus on making CFI fast and practical. Specifically, much of the work on practical CFI is applicable to binaries, and improves performance by enforcing a looser notion of control flow integrity. In this paper, we examine the security implications of such looser notions of CFI: are they still able to prevent code reuse attacks, and if not, how hard is it to bypass its protection? Specifically, we show that with two new types of gadgets, return oriented programming is still possible. We assess the availability of our gadget sets, and demonstrate the practicality of these results with a practical exploit against Internet Explorer that bypasses modern CFI implementations.
Conference Paper
Code Reuse Attacks (CRAs) recently emerged as a new class of security exploits. CRAs construct malicious programs out of small fragments (gadgets) of existing code, thus eliminating the need for code injection. Existing defenses against CRAs often incur large performance overheads or require extensive binary rewriting and other changes to the system software. In this paper, we examine a signature-based detection of CRAs, where the attack is detected by observing the behavior of programs and detecting the gadget execution patterns. We first demonstrate that naive signature-based defenses can be defeated by introducing special “delay gadgets” as part of the attack. We then show how a software-configurable signature-based approach can be designed to defend against such stealth CRAs, including the attacks that manage to use longer-length gadgets. The proposed defense (called SCRAP) can be implemented entirely in hardware using simple logic at the commit stage of the pipeline. SCRAP is realized with minimal performance cost, no changes to the software layers and no implications on binary compatibility. Finally, we show that SCRAP generates no false alarms on a wide range of applications.
Conference Paper
Control Flow Integrity (CFI) provides a strong protection against modern control-flow hijacking attacks. However, performance and compatibility issues limit its adoption. We propose a new practical and realistic protection method called CCFIR (Compact Control Flow Integrity and Randomization), which addresses the main barriers to CFI adoption. CCFIR collects all legal targets of indirect control-transfer instructions, puts them into a dedicated "Springboard section" in a random order, and then limits indirect transfers to flow only to them. Using the Springboard section for targets, CCFIR can validate a target more simply and faster than traditional CFI, and provide support for on-site target-randomization as well as better compatibility. Based on these approaches, CCFIR can stop control-flow hijacking attacks including ROP and return-into-libc. Results show that ROP gadgets are all eliminated. We observe that with the wide deployment of ASLR, Windows/x86 PE executables contain enough information in relocation tables which CCFIR can use to find all legal instructions and jump targets reliably, without source code or symbol information. We evaluate our prototype implementation on common web browsers and the SPEC CPU2000 suite: CCFIR protects large applications such as GCC and Firefox completely automatically, and has low performance overhead of about 3.6%/8.6% (average/max) using SPECint2000. Experiments on real-world exploits also show that CCFIR-hardened versions of IE6, Firefox 3.6 and other applications are protected effectively.
Conference Paper
Code Reuse-based Attacks (popularly known as CRA) are becoming increasingly notorious because of their ability to reuse existing code, and evade the guarding mechanisms in place to prevent code injection-based attacks. Among the recent code reuse-based exploits, Jump Oriented Programming (JOP) captures short sequences of existing code ending in indirect jumps or calls (known as gadgets), and utilizes them to cause harmful, unintended program behavior. In this work, we propose a novel, easily implementable algorithm, called JOP-alarm, that computes a score value to assess the potential for JOP attack, and detects possibly harmful program behavior. We demonstrate the effectiveness of our algorithm using published JOP code, and test the false positive alarm rate using several unmodified SPEC2006 benchmarks.
Conference Paper
We present new techniques that allow a return-into-libc attack to be mounted on x86 exe- cutables that calls no functions at all. Our attack combines a large number of short instruction sequences to build gadgets that allow arbitrary computation. We show how to discover such instruction sequences by means of static analysis. We make use, in an essential way, of the properties of the x86 instruction set.
Conference Paper
Return-oriented programming is an effective code-reuse attack in which short code sequences ending in a ret instruction are found within existing binaries and executed in arbitrary order by taking control of the stack. This allows for Turing-complete behavior in the target program without the need for injecting attack code, thus significantly negating current code injection defense efforts (e.g., W⊕X). On the other hand, its inherent characteristics, such as the reliance on the stack and the consecutive execution of return-oriented gadgets, have prompted a variety of defenses to detect or prevent it from happening. In this paper, we introduce a new class of code-reuse attack, called jump-oriented programming. This new attack eliminates the reliance on the stack and ret instructions (including ret-like instructions such as pop+jmp) seen in return-oriented programming without sacrificing expressive power. This attack still builds and chains functional gadgets, each performing certain primitive operations, except these gadgets end in an indirect branch rather than ret. Without the convenience of using ret to unify them, the attack relies on a dispatcher gadget to dispatch and execute the functional gadgets. We have successfully identified the availability of these jump-oriented gadgets in the GNU libc library. Our experience with an example shellcode attack demonstrates the practicality and effectiveness of this technique.