Re: Sabotaged PaXtest (was: Re: Patch 4/6 randomize the stack pointer)

pageexec
2005-02-02T12:18:53Z

> Umm, so exactly how many applications use multithreading (or otherwise
> trigger the GLIBC mprotect call), and how many applications use nested
> functions (which is not ANSI C compliant, and as a result, very rare)?

i think you're missing the whole point of paxtest. it's not about what
glibc et al. do or don't do. it's about what an exploit can do (by
virtue of forcing the exploited application to do something). if your
line of thinking was correct, then why didn't you also object to the
fact that the paxtest applications overflow their own stack/heap/etc?
or that they put 'shellcode' onto the stack/heap/etc and invoke it by
abusing a memory corrupting bug? surely no sane real-life application
does any of this.

so once again, let me explain what paxtest does. it tests PaX for its
claims. since PaX claims to be an intrusion prevention system, paxtest
tries to simulate said intrusions (in particular, we're talking about
exploiting memory corruption bugs). the stress is on 'simulate'. none
of the paxtest applications are full blown exploits. nor do they need
to be. knowing what PaX does (or claims to do), it's very easy to design
and write small applications that perform the core steps of an exploit
that may be able to break the protection mechanisms. i.e., any 'real'
exploit would eventually have to perform these core steps, so by ensuring
that they don't work (at least when the PaX claims stand) we can ensure
that no real life exploit would work either.

now let's get back to mprotect(), nested functions, etc. when an exploit
writer knows that the only barrier that prevents him from executing his
shellcode is a circumventible memory protection, then guess what, he'll
first try to circumvent said memory protection then execute his shellcode
as usual. since memory protection is controlled by mmap/mmprotect, his
goal will be to somehow force the exploited application to end up calling
these functions to get an executable region holding his shellcode.

your concerns would be valid if this was impossible to achieve by an
exploit, sadly, you'd be wrong too, it's possible to force an exploited
application to call something like dl_make_stack_executable() and then
execute the shellcode. there're many ways of doing this, the simplest
(in terms of lines of code) was chosen for paxtest. or put another way,
would you still argue that the use of the nested function trampoline
is sabotage whereas an exploit forcing a call to dl_make_stack_executable()
isn't? because the two achieve the exact same thing, they open up the
address space (or part of it, depending on the intrusion prevention
system) for shellcode execution.

one thing that paxtest didn't get right in the 'kiddie' mode is that
it still ran with an executable stack, that was not the intention but
rather an oversight, it'll be fixed in the next release. still, this
shouldn't leave you with a warm and fuzzy feeling about the security
of intrusion prevention systems that 'pass' the 'kiddie' mode but fail
the 'blackhat' mode, in the real life out there, only the latter matters
(if for no other reason, then for natural evolution/adaptation of
exploit writers).