Backward-edge control-flow hijacking via stack buffer overflow is the holy grail of software exploitation. The ability to directly control critical stack data and the hijacked target makes this exploitation strategy particularly appealing for attackers. As a result, the community has deployed strong backward-edge protections such as shadow stacks or stack canaries, forcing attackers to resort to less ideal e.g., heap-based exploitation strategies. However, such mitigations commonly rely on one key assumption, namely an attacker relying on return address corruption to directly hijack control flow upon function return.
In this paper, we present exceptions to this assumption and show attacks based on backward-edge control-flow hijacking without the direct hijacking are possible. Specifically, we demonstrate that stack corruption can cause exception handling to act as a confused deputy and mount backward-edge control-flow hijacking attacks on the attacker’s behalf. This strategy
provides overlooked opportunities to divert execution to attacker-controlled catch handlers (a paradigm …
Backward-edge control-flow hijacking via stack buffer overflow is the holy grail of software exploitation. The ability to directly control critical stack data and the hijacked target makes this exploitation strategy particularly appealing for attackers. As a result, the community has deployed strong backward-edge protections such as shadow stacks or stack canaries, forcing attackers to resort to less ideal e.g., heap-based exploitation strategies. However, such mitigations commonly rely on one key assumption, namely an attacker relying on return address corruption to directly hijack control flow upon function return.
In this paper, we present exceptions to this assumption and show attacks based on backward-edge control-flow hijacking without the direct hijacking are possible. Specifically, we demonstrate that stack corruption can cause exception handling to act as a confused deputy and mount backward-edge control-flow hijacking attacks on the attacker’s behalf. This strategy
provides overlooked opportunities to divert execution to attacker-controlled catch handlers (a paradigm we term Catch Handler Oriented Programming or CHOP) and craft powerful primitives
such as arbitrary code execution or arbitrary memory writes. We find CHOP-style attacks to work across multiple platforms (Linux, Windows, macOS, Android and iOS). To analyze the uncovered attack surface, we survey popular open-source packages and study the applicability of the proposed exploitation techniques. Our analysis shows that suitable exception handling
targets are ubiquitous in C++ programs and exploitable exception handlers are common. We conclude by presenting three end-to-end exploits on real-world software and proposing changes to deployed mitigations to address CHOP.
This paper explored the weaknesses and risks associated with modern exception handlers (across all major OS and architectures) in unwinding attacker-controlled state. The most powerful example is a bypass of stack canaries where a function throws an exception after the overflow but before the function return; the exception handler would eventually execute attacker-controlled memory.
There is an attempt to quantify the overall impact of this mitigation bypass by looking at the Debian repos for code that uses exception handlers, but it is quite context sensitive. The paper concludes with three CVEs that would be exploitable with current mitigations (stack canaries, etc.) using the new technique.