Puneet Varma (Editor)

Control flow integrity

Updated on
Edit
Like
Comment
Share on FacebookTweet on TwitterShare on LinkedInShare on Reddit

Control-flow integrity (CFI) is a general term for computer security techniques which prevent a wide variety of malware attacks from redirecting the flow of execution of a program. Associated techniques include Code-Pointer Separation (CPS), Code-Pointer Integrity (CPI), stack canaries, shadow stacks, and vtable pointer verification.

Contents

Related implementations are available in Clang, Microsoft's Control Flow Guard and Return Flow Guard, Google's Indirect Function-Call Checks and Reuse Attack Protector (RAP).

Microsoft Control Flow Guard

Control Flow Guard (CFG) was first released for Windows 8.1 Update 3 (KB3000850) in November 2014. Developers can add CFG to their programs by adding the /guard:cf linker flag in Visual Studio 2015 or newer.

Summary

CFG operates by creating a per-process bitmap, where a set bit indicates that the address is a valid destination. Before performing each indirect function call, the application checks if the destination address is in the bitmap. If the destination address is not in the bitmap, the program terminates. This makes it more difficult for an attacker to exploit a use-after-free by replacing an object's contents and then using an indirect function call to execute a payload.

Implementation Details

For all protected indirect function calls, the _guard_check_icall function is called, which performs the following steps:

  1. Convert the target address to an offset and bit number in the bitmap.
    1. The highest 3 bytes are the byte offset in the bitmap
    2. The bit offset is a 5-bit value. The first four bits are the 4th through 8th low-order bits of the address.
    3. The 5th bit of the bit offset is set to 0 if the destination address is aligned with 0x10 (last four bits are 0), and 1 if is not.
  2. Examine the target's address value in the bitmap
    1. If the target address is in the bitmap, return without an error.
    2. If the target address is not in the bitmap, terminate the program.

Bypass Techniques

There are several generic techniques for bypassing CFG:

  • Set the destination to code located in a non-CFG module loaded in the same process.
  • Find an indirect call that was not protected by CFG.
  • Use a function call with a different number of arguments than the call is designed for, causing a stack misalignment, and code execution after the function returns (patched in Win 10).
  • Use a function call with the same number of arguments, but one of pointers passed is treated as an object and writes to a pointer-based offset, allowing overwriting a return address.
  • Overwrite the function call used by CFG to validate the address (patched in March 2015)
  • Use a controlled-write primitive to overwrite an address on the stack (since the stack is not protected by CFG)
  • References

    Control-flow integrity Wikipedia