03 April 2017, 15:35, Track 1
Session chair: Heng Yin, University of California, Riverside, USA
Strict Virtual Call Integrity Checking for C++ Binaries
Mohamed Elsabagh, Dan Fleck, Angelos Stavrou
Modern operating systems are equipped with defenses that render legacy code injection attacks inoperable. However, attackers can bypass these defenses by crafting attacks that reuse existing code in a program’s memory. One of the most common classes of attacks manipulates memory data used indirectly to execute code, such as function pointers. This is especially prevalent in C++ programs, since tables of function pointers (vtables) are used by all major compilers to support polymorphism. In this paper, we propose VCI, a binary rewriting system that secures C++ binaries against vtable attacks. VCI works directly on stripped binary files. It identifies and reconstructs various C++ semantics from the binary, and constructs a strict CFI policy by resolving and pairing virtual function calls (vcalls) with precise sets of target classes. The policy is enforced by instrumenting checks into the binary at vcall sites. Experimental results on SPEC CPU2006 and Firefox show that VCI is significantly more precise than state-of-the-art binary solutions. Testing against the ground truth from the source-based defense GCC VTV, VCI achieved greater than 60% precision in most cases, accounting for at least 48% to 99% additional reduction in the attack surface compared to the state-of-the-art binary defenses. VCI incurs a 7.79% average runtime overhead which is comparable to the state-of-the-art. In addition, we discuss how VCI defends against real-world attacks, and how it impacts advanced vtable reuse attacks such as COOP.
BinSequence: Fast, Accurate and Scalable Binary Code Reuse Detection
He Huang, Amr Youssef, Mourad Debbabi
Code reuse detection is a key technique in reverse engineering. However, existing source code similarity comparison techniques are not applicable to binary code. Moreover, compilers have made this problem even more difficult due to the fact that different assembly code and control flow structures can be generated by the compilers even when implementing the same functionality. To address this problem, we present a fuzzy matching approach to compare two functions. We first obtain an initial mapping between basic blocks by leveraging the concept of longest common subsequence on the basic block level and execution path level. We then extend the achieved mapping using neighborhood exploration. To make our approach applicable to large data sets, we designed an effective filtering process using Minhashing. Based on the proposed approach, we implemented a tool named BinSequence and conducted extensive experiments with it. Our results show that given a large assembly code repository with millions of functions, BinSequence is efficient and can attain high quality similarity ranking of assembly functions with an accuracy of above 90%. We also present several practical use cases including patch analysis, malware analysis and bug search.
PrivWatcher: Non-bypassable Monitoring and Protection of Process Credentials from Memory Corruption Attacks
Quan Chen, Ahmed M. Azab, Guru Ganesh, Peng Ning
Commodity operating systems kernels are typically implemented using low-level unsafe languages, which leads to the inevitability of memory corruption vulnerabilities. Multiple defense techniques are widely adopted to mitigate the impact of memory corruption on executable code and control data. Nevertheless, there has not been much attention to defend against corruption of non-control data despite the fact that previous incidents of kernel exploitation showed that corrupting non-control data is a real threat. We present PrivWatcher, a framework for monitoring and protecting the integrity of process credentials and their usage contexts from memory corruption attacks. PrivWatcher solves multiple challenges to achieve this objective. It introduces techniques to isolate and protect the data that define process credentials and guarantee the locality of this data within the protected memory. Then, by adopting a dual reference monitor model, it guarantees the Time of Check To Time of Use (TOCTTOU) consistency between verification and usage contexts for process credentials. Moreover, it provides a secure mechanism that allows the presumably protected kernel code to verify the protected data without relying on unprotected data fields. PrivWatcher provides non-bypassable integrity assurances for process credentials and can be adapted to enforce a variety of integrity policies. In this paper, we demonstrate an application of PrivWatcher that enforces the original semantics of the OS kernel’s access control policy: a change in process privileges is legitimate only if an uncompromised kernel would have allowed it. We implemented a PrivWatcher prototype to protect Ubuntu Linux running on x86-64. Evaluation of our prototype showed that PrivWatcher is effective and efficient.
Breaking Ad-hoc Runtime Integrity Protection Mechanisms in Android Financial Apps
Taehun Kim, Hyeonmin Ha, Seoyoon Choi, Jaeyeon Jung, Byung-Gon Chun
To protect customers’ sensitive information, many mobile financial applications include steps to probe the runtime environment and abort their execution if the environment is deemed to have been tampered with. This paper investigates the security of such self-defense mechanisms used in 76 popular financial Android apps in the Republic of Korea. Our investigation found that existing tools fail to analyze these Android apps effectively because of their highly obfuscated code and complex, non-traditional control flows. We overcome this challenge by extracting a call graph with a self-defense mechanism, from a detailed runtime trace record of a target app’s execution. To generate the call graph, we identify the causality between the system APIs (Android APIs and system calls) used to check device rooting and app integrity, and those used to stop an app’s execution. Our analysis of 76 apps shows that we can pinpoint methods to bypass a self-defense mechanism using a causality graph in most cases. We successfully bypassed self-defense mechanisms in 67 out of 73 apps that check device rooting and 39 out of 44 apps that check app integrity. While analyzing the self-defense mechanisms, we found that many apps rely on third-party security libraries for their self-defense mechanisms. Thus we present in-depth studies of the top five security libraries. Our results demonstrate the necessity of a platform-level solution for integrity checks.
DataShield: Configurable Data Confidentiality and Integrity
Scott A. Carr, Mathias Payer
Applications written in C/C++ are prone to memory corruption, which allows attackers to extract secrets or gain control of the system. With the rise of strong control-flow hijacking defenses, non-control data attacks have become the dominant threat. As vulnerabilities like HeartBleed have shown, such attacks are equally devastating. Data Confidentiality and Integrity (DCI) is a low-overhead non-control-data protection mechanism for systems software. DCI augments the C/C++ programming languages with an- notations, allowing the programmer to protect selected data types. The DCI compiler and runtime system prevent illegal reads (confidentiality) and writes (integrity) to instances of these types. The programmer selects types that contain security critical information such as passwords, cryptographic keys, or identification tokens. Protecting only this critical data greatly reduces performance overhead relative to complete memory safety. Our prototype implementation of DCI, DataShield, shows the applicability and efficiency of our approach. For SPEC CPU2006, the performance overhead is at most 16.34%. For our case studies, we instrumented mbedTLS, astar, and libquantum to show that our annotation approach is practical. The overhead of our SSL/TLS server is 35.7% with critical data structures protected at all times. Our security evaluation shows DataShield mitigates a recently discovered vulnerability in mbedTLS.