Well, you can’t do #3 as easily anymore. I have introduced pinsyscall(2), which lets ld.so [dynamic programs] or crt0 [static programs] tell the kernel where the SPECIFIC execve entry point is, and any other entry point is invalid and kills the program.
Now the attacker must precisely know where that specific system call nstruction [sic] is.
It is very cheap code relative to the hurdle it provides.
In 2023, in his CanSecWest talk,
De Raadt said that the goal of this mitigation was to make “poping shells
harder”, in case an attacker knows where the libc is mapped, but doesn’t know
execve stub is.
This is completely useless:
- An attacker able to perform ROP doesn’t need
execveto do nasty things.
- An attacker able to perform ROP won’t have any trouble crafting a read
primitive to find where the
execvestub is, either by walking the whole memory range, or more likely by simply reading relocations/symbols table, ……
- An attacker able to perform ROP can simply use the libc stub, instead of issuing raw syscalls, …
- An attacker able to devise where the libc is mapped is likely able to devise
There are even more low-hanging bypasses, left as an exercise to the reader.