7

I have been learning about using stack overflows to get arbitrary code execution, one of the tricks used is overwriting the return address to make control flow go the way you want it. Assuming our system has NX bit.

What if we made the CPU instruction set require a "landing pad" instruction for any location that it ret or jmps to?

The idea is that a program would terminate with some kind of error if it jumps to a non landing pad instruction.

Would this stop the ability to make ROP gadgets? Do you think this ISA would be a lot more secure? Has the idea been tried in the past?

schroeder
  • 123,438
  • 55
  • 284
  • 319
river
  • 183
  • 4
  • are you asking about the effectiveness of something like [LandHere](http://landhere.galois.com/)? – julian May 07 '17 at 17:40
  • It is difficult to evaluate the benefits of such a system without an objective standard or definition of security. I do not know if such a standard or definition exists, so your question "Do you think this ISA would be a lot more secure?" may not be answerable. – julian May 07 '17 at 18:08
  • 1
    You may want to look into Intel's [CET](https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-enforcement-technology-preview.pdf), which essentially does this. It's basically [CFG](https://msdn.microsoft.com/en-us/library/windows/desktop/mt637065(v=vs.85).aspx) but in hardware, and using a shadow stack. – forest Dec 19 '17 at 04:44

1 Answers1

1

Your question mentions a lot of technology without much structure so I'll break it down technology by technology in order to construct a correct answer about where we are with the kind of mitigation technique you describe.

As you mentioned one such way to gain arbitrary code execution of an application is via a Stack Buffer Overflow. This is an attack where a stack allocated buffer can be overwritten with more data than the buffer is meant to hold as a result the stack is smashed with data which allows us to gain control of the instruction pointer.

One mitigation designed to help prevent against arbitrary code execution is the use of No Execute (NX). The idea behind NX is to mark memory pages as "no execute" this means that any code residing in NX marked pages will not be executed by the CPU. While this does not prevent Stack Buffer Overflows it does make gaining arbitrary control of the system more difficult due to needing somewhere to store our shellcode. (Simplification).

A bypass technique for NX is the concept of Return Oriented Programming (ROP) this is where we can use existing instructions in the application or loaded modules called "gadgets" in order to bypass NX by setting the required page back to executable. (Simplification).

The idea you are describing is as pointed out in the comments similar to Control Flow Integrity (CFI). At a high level this mitigation works by identifying which functions in an application are valid targets for indirect calls. In the case of CFG this is managed by the Windows kernel which maintains the state that identifies valid call targets and handles the logic which actually verifies the indirect calls. CET is similar however it is implemented in hardware and uses the concept of a "shadow stack" which stores CPU-stored copies of valid return addresses. There are many implementations of CFI each vary slightly but all aim to solve the problem of ROP chains being used to bypass NX and other mitigations.

It should be noted that none of this stops stack overflows, they can still exist in code as in, the bugs can still be present. But by stacking exploit-mitigations such as NX, ASLR, CFI, Stack Cookies it makes such a vulnerability significantly more difficult to exploit.

J--
  • 278
  • 1
  • 12