Re: Announcing RSX - non exec stack/heap module
Paul Starzetz wrote: Crispin Cowan wrote: It is not very hard to mmap the libc code as non-executable are into main memory. After the regular programm code jumps into some libc function, we can check in the gp() handler if the gp fault resulted from jumping into the libc area by a ret (the target address should still be on the stack) or by a regular call/jmp instruction. That's an interesting idea, but the performance penalty will be substantial. You will pay for (at least) two system calls per library call. In early StackGuard research, we experimented with hardware protection methods that imposed 2 syscalls per function call, and the overhead was between 500% and 10,000%, which just isn't realistic for prodution use. Yes and no! I have written such a code for rsx. The overhead is more precisely 1x page fault and 1x general protection fault + the emulation code (jmp/call/ret), which is not equal to 2x syscall + emulation, but indeed of similar magnitude. However it works. I presume that what you're doing here is to mark the library pages non-executable, and then make them executable when you get a page fault due to some code trying to make a library call. If so, how do you distinguish between legitmate calls into the library, and bogus calls made by a buffer overflow? Note that a simpler protection (but maybe not so effective) can be done by means of ld.so. What does people mean if they talk about ret-into-libc? ret-into-libc is just a common name for the technique. It is not technically precise. The general case is to change a function return address so that it jumps to code that does exec(sh). The intructions that do this don't have to be in libc, and don't have to be in a library, they can be in the program's main executable body. It's just convenient for the attacker to use libc, because libc necessarily has exec(sh) in it, and most programs link to libc. Making libc non-executable is effectively another level of obscurity defense. It makes existing attack scripts break, but can be bypassed in most cases if the attacker is willing to take the time to find the right sequence of bytes somewhere in the body of the victim program. So now assume we doesn't link the libc-plt to the real libc location - Same effect: you deny the attacker access to the libc code body, forcing them to look elsewhere for a fairly common sequence of a half dozen bytes in an executable page. Thanks to Solar Designer for pointing out that my previous claim that non-executable stacks heaps can always be bypassed is inaccurate. They can often be bypassed, but not always. Crispin -- Crispin Cowan, Ph.D. Chief Scientist, WireX Communications, Inc. http://wirex.com Security Hardened Linux Distribution: http://immunix.org Available for purchase: http://wirex.com/Products/Immunix/purchase.html
Re: Announcing RSX - non exec stack/heap module
Crispin Cowan wrote: I presume that what you're doing here is to mark the library pages non-executable, and then make them executable when you get a page fault due to some code trying to make a library call. If so, how do you distinguish between legitmate calls into the library, and bogus calls made by a buffer overflow? No, because there is no exec/noexec flag on x86 architecture - otherwise the whole thing would be trivial. I map a sort of ´zombie´ or ´ghost´ libc into the RSX address space, marking those pages as PROT_NONE. I also map a regular copy of libc at some other location. There are further transition handlers in the gp() and pf() trap code handling the segment transitions between ´normal´ code and ´libc´ code (the mentioned ret/call/jmp emulation routines). ret-into-libc is just a common name for the technique. It is not technically precise. The general case is to change a function return address so that it jumps to code that does exec(sh). The intructions that do this don't have to be in libc, and don't have to be in a library, they can be in the program's main executable body. It's just convenient for the attacker to use libc, because libc necessarily has exec(sh) in it, and most programs link to libc. Ok but I´m talking only about dynamically linked libc. So now assume we doesn't link the libc-plt to the real libc location - Same effect: you deny the attacker access to the libc code body, forcing them to look elsewhere for a fairly common sequence of a half dozen bytes in an executable page. Hm, I´m not convinced that this code is so common. One must look for a sequence similar to mov value, %ebx; mov SYSCALL, %eax; int 0x80; in order to do something dangerous after overflowing a stack buffer. I think that some level of randomization in the libc location and the plt linking code would provide a simple (but not complete) defense against simple jump-into-system()-plt and similar attack. Paul Starzetz.
Re: Announcing RSX - non exec stack/heap module
Crispin Cowan wrote: It is not very hard to mmap the libc code as non-executable are into main memory. After the regular programm code jumps into some libc function, we can check in the gp() handler if the gp fault resulted from jumping into the libc area by a ret (the target address should still be on the stack) or by a regular call/jmp instruction. That's an interesting idea, but the performance penalty will be substantial. You will pay for (at least) two system calls per library call. In early StackGuard research, we experimented with hardware protection methods that imposed 2 syscalls per function call, and the overhead was between 500% and 10,000%, which just isn't realistic for prodution use. Yes and no! I have written such a code for rsx. The overhead is more precisely 1x page fault and 1x general protection fault + the emulation code (jmp/call/ret), which is not equal to 2x syscall + emulation, but indeed of similar magnitude. However it works. Note that a simpler protection (but maybe not so effective) can be done by means of ld.so. What does people mean if they talk about ret-into-libc? I assume we speak about ret-into-plt, where libc is linked to, because this is the only information an attacker can obtain by analyzing the binary. Libc can be mmaped at some random location, right? So now assume we doesn't link the libc-plt to the real libc location - instead we link it to a intermediate random glue code piece. The protection arises from the fact that it is hard to guess the location of this intermediate glue segment (and it is hard to guess the real libc vma too). So the attacker neither easily jump into some offset (skipping the ret checking code) in the glue code, nor directly jump into some real libc function. The addresses of the glue code and libc should change with every execve() and fork() (to prevent binary search...). The glue code does now the similar thing that a pf() or gp() hook would - look at the stack to switch between the cases 1) call from legal .text code into plt or 2) ret from buffer overflow into plt. This again does not protect against ret-into-text where some libc function (via plt) is called. But maybe one can make this harder using another trick. I think this case would also have a clear signature on the stack. (hm what about jumping at libc-call-in-text - 4, 8, ... offset?) Paul.
Re: Announcing RSX - non exec stack/heap module
Thomas Dullien wrote: It would appearat first glance that RSX uses the same technique as PAX. Naturally, the PAX and RSX teams should confer to make a definitive statement on similarities and differences. Just for the record, the technique bears no similarity. PAX provides real, non-executable PAGES on x86 -- RSX remaps the heap segments outside of the code segment limit. To be more precise: RSX does _not_ provide non-exec stack, heap and so on but the 'complement' speak executable code area. The segments which are remapped are _not_ the heap(s), speak data segments, but the code (marked as rx-p) areas. The basic idea while writing RSX was not to provide some heavy artillery but a small, very low penalty kernel module stopping not 100 but maybe 95% of wide spread local remote attacks towards Linux machines. There cannot be a doubt that installing the module to protect few but endangered applications (like sshd, rshd, rpc) improves the system security. sincerely, Paul Starzetz
Re: Announcing RSX - non exec stack/heap module
Paul Starzetz wrote: One don't even need code in the libc. There may also be code in regular code 'segments' mmapped from the binary valuable for jumping into them. True. libc is just the common point of reference, because nearly all programs link to it, so it's assured to be there. However it is possible to develop a defense agains jumping into libc code if the performance is not the most important thing. It is not very hard to mmap the libc code as non-executable are into main memory. After the regular programm code jumps into some libc function, we can check in the gp() handler if the gp fault resulted from jumping into the libc area by a ret (the target address should still be on the stack) or by a regular call/jmp instruction. That's an interesting idea, but the performance penalty will be substantial. You will pay for (at least) two system calls per library call. In early StackGuard research, we experimented with hardware protection methods that imposed 2 syscalls per function call, and the overhead was between 500% and 10,000%, which just isn't realistic for prodution use. Of course this again doesn't protect against function-pointer overflows but on the other hand eliminates again 90% of the potential vulnerabilities. But can there be a 100% protection at all? There can be 100% protection for limited threat models. Consumers of a technology need to evaluate whether the threat model matches their needs. Crispin -- Crispin Cowan, Ph.D. Chief Scientist, WireX Communications, Inc. http://wirex.com Security Hardened Linux Distribution: http://immunix.org Available for purchase: http://wirex.com/Products/Immunix/purchase.html
Re: Announcing RSX - non exec stack/heap module
Paul Starzetz wrote: Hi folks, I´m announcing a novell Linux kernel security module implementing non-exec stack and non-exec heap. I think this is the first Linux module providing non-exec heap areas. It's not the first. This Oct. 28/2000 Bugtraq post http://www.securityfocus.com/archive/1/141901 announces PAX http://pageexec.virtualave.net/ which also provides a non-executable heap segment. Then there is the ensuing discussion over the relative merrits of this and various other forms of buffer overflow defense in these threads: * http://www.securityfocus.com/archive/1/142819 * http://www.securityfocus.com/archive/1/141980 * http://www.securityfocus.com/archive/1/142688 Summary of my personal view only: * non-executable segments do add some security value * non-executable segments is argualy an obscurity defense, because attacks exploiting overflow vulnerabilities that are stopped by non-executable segments can always be re-worked to be return into libc style attacks that bypass the non-executable segment by pointing directly at code in the code segment * this obscurity defense arguably has value, because writing return-into-libc exploits is hard, and hard to make scriptable, because the offsets are fussy Folks unfamiliar with this area should probably read my survey paper that compares various buffer overflow defenses http://immunix.org/StackGuard/discex00.pdf Tecnically RSX provides on the fly page remapping as well as segment descriptor exchanging for particular processes. In the default configuration the remapping base is set to 0x5000. This cause problems with kernels configured to support 2 GB of RAM because the physical RAM is mapped to the region beginning at 0x8000. Different workarounds are imaginable but I don't have the time at the moment to support this. It would appearat first glance that RSX uses the same technique as PAX. Naturally, the PAX and RSX teams should confer to make a definitive statement on similarities and differences. Crispin -- Crispin Cowan, Ph.D. Chief Scientist, WireX Communications, Inc. http://wirex.com Security Hardened Linux Distribution: http://immunix.org Available for purchase: http://wirex.com//Products/Immunix/purchase.html