0

Is it possible to reliably execute arbitrary code from a single overwrite of the Global Offset Table when W^X is enabled? By "reliably" I mean assuming I control only the location pointed to by the instruction pointer and possibly some non-executable data elsewhere.

Why I ask: using the House of Force heap exploit demoed here, it is possible to overwrite arbitrary memory, which makes the GOT an attractive target for hijacking the instruction pointer. However, to make that implementation of the heap overflow work (i.e. get a shell), the author had to inject shellcode to point to from the GOT. If W^X is enabled, this technique would fail. Is there a method (possibly leveraging ROP/JOP?) that overcomes this limitation? The reason I'm having a hard time with this is because in this exploit you only control the instruction pointer, not the stack pointer, so I can't easily see a way to make ROP work, and JOP seems to require control of multiple registers to make it work (but to be honest, implementing JOP is still over my head).

camercu
  • 103
  • 7

2 Answers2

1

W^X simply prevents pages from being both executable and writable simultaneously, so an arbitrary write vulnerability cannot modify executable pages. It does not enforce control flow, so any exploit primitive which permits out-of-order execution of existing code has the potential to bypass it. Other attacks such as SigReturn-Oriented Programming, or SROP (on platforms which are vulnerable to it) and Loop-Oriented Programming, or LOP, are often capable of achieving the same thing.

An example JOP exploit can be seen here.

ROP vs JOP

guest
  • 78
  • 2
1

It is certainly possible, it just depends on the circumstances. As an example of a ret2libc attack, let's say the program takes input from the user into buffer and after having overwritten a GOT entry, the program has a call to strlen(buffer) at some point of execution. Now if you had passed in '/bin/sh' into the buffer and if you had overwritten the entry for strlen with the libc address of system, then while making the call to strlen, '/bin/sh' would be conveniently pushed on to the stack as a parameter to system and a shell would be spawned - with NX enabled and without having an explicit control over the stack pointer.

Now that might sound like a contrived example but it does arise quite often and the difference between 'possible' and 'impossible' is often just clever craftsmanship like this.

rhodeo
  • 524
  • 1
  • 6
  • 14