Devil is Virtual: Reversing Virtual Inheritance in C++ Binaries

The complexities that arise from the implementation of object-oriented concepts in C++ such as virtual dispatch and dynamic type casting have attracted the attention of attackers and defenders alike. Binary-level defenses are dependent on full and precise recovery of class inheritance tree of a given program. While current solutions focus on recovering single and multiple inheritances from the binary, they are oblivious of virtual inheritance. The conventional wisdom among binary-level defenses is that virtual inheritance is uncommon and/or support for single and multiple inheritances provides implicit support for virtual inheritance. In this paper, we show neither to be true. Specifically, (1) we present an efficient technique to detect virtual inheritance in C++ binaries and show through a study that virtual inheritance can be found in non-negligible number (more than 10% on Linux and 12.5% on Windows) of real-world C++ programs including Mysql and Libstdc++. (2) We show that failure to handle virtual inheritance introduces both false positives and false negatives in the hierarchy tree. These falses either introduce attack surface when the hierarchy recovered is used to enforce CFI policies, or make the hierarchy difficult to understand when it is needed for program understanding (e.g., during decompilation). (3) We present a solution to recover virtual inheritance from COTS binaries. We recover a maximum of 95% and 95.5% (GCC -O0) and a minimum of 77.5% and 73.8% (Clang -O2) of virtual and intermediate bases respectively in the virtual inheritance tree.

[1]  Herbert Bos,et al.  MARX: Uncovering Class Hierarchies in C++ Programs , 2017, NDSS.

[2]  Aravind Prakash,et al.  Bloat Factors and Binary Specialization , 2019 .

[3]  Kevin W. Hamlen,et al.  Superset Disassembly: Statically Rewriting x86 Binaries Without Heuristics , 2018, NDSS.

[4]  Sorin Lerner,et al.  Protecting C++ Dynamic Dispatch Through VTable Interleaving , 2016, NDSS.

[5]  Lok-Kwong Yan,et al.  Debloating Software through Piece-Wise Compilation and Loading , 2018, USENIX Security Symposium.

[6]  Xi Chen,et al.  A Tough Call: Mitigating Advanced Code-Reuse Attacks at the Binary Level , 2016, 2016 IEEE Symposium on Security and Privacy (SP).

[7]  Chenxiong Qian,et al.  RAZOR: A Framework for Post-deployment Software Debloating , 2019, USENIX Security Symposium.

[8]  David Brumley,et al.  BYTEWEIGHT: Learning to Recognize Functions in Binary Code , 2014, USENIX Security Symposium.

[9]  Mathias Payer,et al.  Control-Flow Integrity , 2017, ACM Comput. Surv..

[10]  Herbert Bos,et al.  ShrinkWrap: VTable Protection without Loose Ends , 2015, ACSAC 2015.

[11]  Jonathon T. Giffin,et al.  Static detection of C++ vtable escape vulnerabilities in binary code , 2012, NDSS.

[12]  Claudia Eckert,et al.  CastSan: Efficient Detection of Polymorphic C++ Object Type Confusions with LLVM , 2018, ESORICS.

[13]  Cristiano Giuffrida,et al.  VTPin: practical VTable hijacking protection for binaries , 2016, ACSAC.

[14]  Erik van der Kouwe,et al.  TypeSan: Practical Type Confusion Detection , 2016, CCS.

[15]  Heng Yin,et al.  ORIGEN: Automatic Extraction of Offset-Revealing Instructions for Cross-Version Memory Analysis , 2016, AsiaCCS.

[16]  Aravind Prakash,et al.  On Design Inference from Binaries Compiled using Modern C++ Defenses , 2019, RAID.

[17]  Chao Zhang,et al.  VTrust: Regaining Trust on Virtual Calls , 2016, NDSS.

[18]  Ran El-Yaniv,et al.  Estimating types in binaries using predictive modeling , 2016, POPL.

[19]  Dinghao Wu,et al.  Reassembleable Disassembling , 2015, USENIX Security Symposium.

[20]  Xiangke Liao,et al.  Boosting the precision of virtual call integrity protection with partial pointer analysis for C++ , 2017, ISSTA.

[21]  Jeffrey Gennari,et al.  Using Logic Programming to Recover C++ Classes and Methods from Compiled Executables , 2018, CCS.

[22]  Carsten Willems,et al.  Practical Timing Side Channel Attacks against Kernel Space ASLR , 2013, 2013 IEEE Symposium on Security and Privacy.

[23]  Zhenkai Liang,et al.  Neural Nets Can Learn Function Type Signatures From Binaries , 2017, USENIX Security Symposium.

[24]  Christopher Krügel,et al.  Ramblr: Making Reassembly Great Again , 2017, NDSS.

[25]  Di Jin,et al.  Nibbler: debloating binary shared libraries , 2019, ACSAC.

[26]  Aravind Prakash,et al.  DeClassifier: Class-Inheritance Inference Engine for Optimized C++ Binaries , 2019, AsiaCCS.

[27]  Mingwei Zhang,et al.  Protecting COTS Binaries from Disclosure-guided Code Reuse Attacks , 2017, ACSAC.

[28]  Eran Yahav,et al.  Statistical Reconstruction of Class Hierarchies in Binaries , 2018, ASPLOS.

[29]  Yue Chen,et al.  Pinpointing Vulnerabilities , 2017, AsiaCCS.

[30]  Erik van der Kouwe,et al.  VPS: excavating high-level C++ constructs from low-level binaries to protect dynamic dispatching , 2019, ACSAC.

[31]  Priya Narasimhan,et al.  Recovering C++ Objects From Binaries Using Inter-Procedural Data-Flow Analysis , 2014, PPREW'14.

[32]  Scott A. Carr,et al.  CFIXX : Object Type Integrity for C + + Virtual Dispatch , 2017 .

[33]  Dongli Zhang,et al.  NORAX: Enabling Execute-Only Memory for COTS Binaries on AArch64 , 2017, 2017 IEEE Symposium on Security and Privacy (SP).

[34]  Sorin Lerner,et al.  SafeDispatch: Securing C++ Virtual Calls from Memory Corruption Attacks , 2014, NDSS.

[35]  Mathias Payer,et al.  HexType: Efficient Detection of Type Confusion Errors for C++ , 2017, CCS.

[36]  Nael B. Abu-Ghazaleh,et al.  Jump over ASLR: Attacking branch predictors to bypass ASLR , 2016, 2016 49th Annual IEEE/ACM International Symposium on Microarchitecture (MICRO).

[37]  Wenke Lee,et al.  Type Casting Verification: Stopping an Emerging Attack Vector , 2015, USENIX Security Symposium.

[38]  Angelos Stavrou,et al.  Strict Virtual Call Integrity Checking for C++ Binaries , 2017, AsiaCCS.

[39]  Egor Derevenetc,et al.  SmartDec: Approaching C++ Decompilation , 2011, 2011 18th Working Conference on Reverse Engineering.

[40]  Úlfar Erlingsson,et al.  Enforcing Forward-Edge Control-Flow Integrity in GCC & LLVM , 2014, USENIX Security Symposium.

[41]  Mingwei Zhang,et al.  Control Flow Integrity for COTS Binaries , 2013, USENIX Security Symposium.

[42]  Thorsten Holz,et al.  Towards automated integrity protection of C++ virtual function tables in binary programs , 2014, ACSAC.

[43]  Heng Yin,et al.  vfGuard: Strict Protection for Virtual Function Calls in COTS C++ Binaries , 2015, NDSS.

[44]  Niranjan Hasabnis,et al.  Extracting instruction semantics via symbolic execution of code generators , 2016, SIGSOFT FSE.

[45]  Thomas W. Reps,et al.  Recovery of Class Hierarchies and Composition Relationships from Machine Code , 2014, CC.