Hacker News new | ask | show | jobs
by RolfRolles 3222 days ago
As I said to the other user who replied to a similar comment, these observations apply only to exploitation of stack buffer overflows, and hence don't rebut what I've said about this not mitigating ROP as a general technique (which is also used in the exploitation of non-stack-based vulnerabilities like use-after-free).
2 comments

Exactly, but also, ROP is not solely about RET instructions, but the general technique is applicable to other forms of control transfer like unconditional absolute/relative jumps as well. Some time ago I did an analysis on this topic [1] using radare2 - I was curious what number of ROP gadgets is present in a healthy instruction stream (I call those implicit, and those are mostly comprised of function epilogues) and what number of gadgets can be formed by jumping into the "middle" of some instruction (explicit gadgets). The idea was to get rid of dangerous ModRegRm/SIB/XOP prefixes at the compiler level, see last table at [2] for example ModRegRM bytes - if your compiler decides to move something between RAX and {RDX,RBX} it will unavoidably emit C2/C3 bytes as well. Another thing are immediate and constant values, which are literally embedded in the instruction stream so if I have a code like:

   something = 0xc351c131485958
For which the compiler can generate:

   movabs rdx,0xc351c131485958
Just by using unfortunate value for something at the code level I've actually introduced a new gadget into the program:

   pop rax       // 0x58
   pop rcx       // 0x59
   xor rcx, rax  // 0x48 0x31 0xc1
   push rcx      // 0x51
   ret           // 0xc3
Not sure how it turned out, but I heard someone from GCC was trying to implement a mitigation strategy based on this idea.

[1]: https://github.com/shaded-enmity/r2-ropstats [2]: http://www.asmpedia.org/index.php?title=ModRegRM_byte_(32/64...

You have not replied to this:

> To use ROP you need not only the RET instruction, but the code before it. You want to execute some existing function and return only then, not just return.

Ok, you found RET in some unexpected place, like an immediate value. But do you want to execute the code before it? Most likely it is just garbage.

Usually you want to return to mprotect() and then chain somewhere else from it. With this mitigation even if you manage to jump to mprotect() function, you will not be able to make it chain to the next function you want.

Yes, gadgets arising from non-epilogue instances of C2/C3 are used frequently. In fact they are most often critical and the ROP exploit would not work without them.