Ingo Molnar [interview] has announced a new kernel-based security feature for Linux/x86 called "Exec Shield". He describes the patch, which is against the 2.4.20-rc1 kernel, as:
"The exec-shield feature provides protection against stack, buffer or function pointer overflows, and against other types of exploits that rely on overwriting data structures and/or putting code into those structures. The patch also makes it harder to pass in and execute the so-called 'shell-code' of exploits. The patch works transparently, ie. no application recompilation is necessary."
Ingo goes on to provide a lengthy and quite informative description of Exec Shield, beginning with a little background describing the problem that the patch works to fix. This is followed with a longer section devoted to describing how the solution has been implemented, followed by an examination of its limitations. The final section describes how the patch is installed and used. Read on for Ingo's excellent writeup, and some of the resulting discussion.
From: Ingo Molnar To: linux-kernel mailing list Subject: [Announcement] "Exec Shield", new Linux security feature Date: Fri, 2 May 2003 12:37:23 -0400 (EDT) We are pleased to announce the first publically available source code release of a new kernel-based security feature called the "Exec Shield", for Linux/x86. The kernel patch (against 2.4.21-rc1, released under the GPL/OSL) can be downloaded from: http://redhat.com/~mingo/exec-shield/ The exec-shield feature provides protection against stack, buffer or function pointer overflows, and against other types of exploits that rely on overwriting data structures and/or putting code into those structures. The patch also makes it harder to pass in and execute the so-called 'shell-code' of exploits. The patch works transparently, ie. no application recompilation is necessary. Background: ----------- It is commonly known that x86 pagetables do not support the so-called executable bit in the pagetable entries - PROT_EXEC and PROT_READ are merged into a single 'read or execute' flag. This means that even if an application marks a certain memory area non-executable (by not providing the PROT_EXEC flag upon mapping it) under x86, that area is still executable, if the area is PROT_READ. Furthermore, the x86 ELF ABI marks the process stack executable, which requires that the stack is marked executable even on CPUs that support an executable bit in the pagetables. This problem has been addressed in the past by various kernel patches, such as Solar Designer's excellent "non-exec stack patch". These patches mostly operate by using the x86 segmentation feature to set the code segment 'limit' value to a certain fixed value that points right below the stack frame. The exec-shield tries to cover as much virtual memory via the code segment limit as possible - not just the stack. Implementation: --------------- The exec-shield feature works via the kernel transparently tracking executable mappings an application specifies, and maintains a 'maximum executable address' value. This is called the 'exec-limit'. The scheduler uses the exec-limit to update the code segment descriptor upon each context-switch. Since each process (or thread) in the system can have a different exec-limit, the scheduler sets the user code segment dynamically so that always the correct code-segment limit is used. the kernel caches the user segment descriptor value, so the overhead in the context-switch path is a very cheap, unconditional 6-byte write to the GDT, costing 2-3 cycles at most. Furthermore, the kernel also remaps all PROT_EXEC mappings to the so-called ASCII-armor area, which on x86 is the addresses 0-16MB. These addresses are special because they cannot be jumped to via ASCII-based overflows. E.g. if a buggy application can be overflown via a long URL: http://somehost/buggy.app?realyloooooooooooooooooooong.123489719875 then only ASCII (ie. value 1-255) characters can be used by attackers. If all executable addresses are in the ASCII-armor, then no attack URL can be used to jump into the executable code - ie. the attack cannot be successful. (because no URL string can contain the \\0 character.) E.g. the recent sendmail remote root attack was an ASCII-based overflow as well. With the exec-shield activated, and the 'cat' binary relinked into the the ASCII-armor, the following layout is created: $ ./cat-lowaddr /proc/self/maps 00101000-00116000 r-xp 00000000 03:01 319365 /lib/ld-2.3.2.so 00116000-00117000 rw-p 00014000 03:01 319365 /lib/ld-2.3.2.so 00117000-0024a000 r-xp 00000000 03:01 319439 /lib/libc-2.3.2.so 0024a000-0024e000 rw-p 00132000 03:01 319439 /lib/libc-2.3.2.so 0024e000-00250000 rw-p 00000000 00:00 0 01000000-01004000 r-xp 00000000 16:01 2036120 /home/mingo/cat-lowaddr 01004000-01005000 rw-p 00003000 16:01 2036120 /home/mingo/cat-lowaddr 01005000-01006000 rw-p 00000000 00:00 0 40000000-40001000 rw-p 00000000 00:00 0 40001000-40201000 r--p 00000000 03:01 464809 locale-archive 40201000-40207000 r--p 00915000 03:01 464809 locale-archive 40207000-40234000 r--p 0091f000 03:01 464809 locale-archive 40234000-40235000 r--p 00955000 03:01 464809 locale-archive bfffe000-c0000000 rw-p fffff000 00:00 0 In the above layout, the highest executable address is 0x01003fff, ie. every executable address is in the ASCII-armor. this means that not only the stack is non-executable, but lots of mmap()-ed data areas and the malloc() heap is non-executable as well. (some data areas are still executable, but most of them are not.) the first 1MB of the ASCII-armor is left unused to provide NULL pointer dereference protection and leave space for 16-bit emulation mappings used by XFree86 and others. Compare this with the memory layout without exec-shield: 08048000-0804b000 r-xp 00000000 16:01 3367 /bin/cat 0804b000-0804c000 rw-p 00003000 16:01 3367 /bin/cat 0804c000-0804e000 rwxp 00000000 00:00 0 40000000-40012000 r-xp 00000000 16:01 3759 /lib/ld-2.2.5.so 40012000-40013000 rw-p 00011000 16:01 3759 /lib/ld-2.2.5.so 40013000-40014000 rw-p 00000000 00:00 0 40018000-40129000 r-xp 00000000 16:01 4058 /lib/libc-2.2.5.so 40129000-4012f000 rw-p 00111000 16:01 4058 /lib/libc-2.2.5.so 4012f000-40133000 rw-p 00000000 00:00 0 bffff000-c0000000 rwxp 00000000 00:00 0 In this layout none of the executable areas are in the ASCII-armor, plus the exec-limit is 0xbfffffff (3GB) - ie. including all userspace mappings. Note that the kernel will relocate every shared-library to the ASCII-armor, but the binary address is determined at link-time. To ease the relinking of applications to the ASCII-armor, Arjan Van de Ven has written a binutils patch (binutils-2.13.90.0.18-elf-small.patch), which adds a new 'ld' flag "ld -melf_i386_small" (or "gcc -Wl,-melf_i386_small") to relink applications into the ASCII-armor. (The patch can be found at the exec-shield URL as well.) Overhead: --------- the patch was designed to be as efficient as possible. There's a very minimal (couple of cycles) tracking overhead for every PROT_MMAP system-call, plus there's the 2-3 cycles cost per context-switch. Limitations: ------------ This feature will not protect against every type of attack. E.g. if an overflow can be used to overwrite a local variable which changes the flow of control in a way that compromises the system. But we do believe that this feature will stop every attack that is purely operating by overflowing the return address on the stack, or overflowing a function pointer in the heap. Furthermore, exec-shield makes it quite hard to mount a successful attack even in the other cases, because it inhibits the execution of exploit shell-code, in most cases. also, if the overflow is within the exec-shield itself (e.g. within the data section of one of the shared library objects in the ASCII-armor) then the overflow might be possible to exploit. All in one, exec-shield is one barrier against attacks, not blanket 100% protection in any way. The most efficient security can be provided by installing as many layers as possible. To provide as good protection as possible, there's no trampoline workaround in the exec-shield code - ie. exec-limit violations in the trampoline case are never let through. Applications that need to rely on gcc trampolines will have to use the per-binary ELF flag to make the stack executable again. (The ELF flag is the same as used by Solar Designer's non-exec stack patch, to provide as much compatibility with existing non-exec-stack installations as possible.) The exec-shield feature will uncover applications that incorrectly assumed that PROT_READ allows execution on x86. One such example is the XFree86 module loader. The latest XFree86 on rawhide.redhat.com fixes this problem. For those who cannot install the XFree86 bugfix at the moment there's a workaround added by the patch, which can be activated via: echo 1 > /proc/sys/kernel/X-workaround This will make every iopl() using application (such as X) have the exec-shield disabled. Other applications (sendmail, etc.) will still have the exec-shield enabled. This workaround is default-off. We strongly encourage to solve this problem by upgrading X, or by using the 'chkstk' utility to make X's stack forced-executable. Using it: --------- Apply the exec-shield-2.4.21-rc1-B6 kernel patch to the 2.4.21-rc1 kernel, recompile & install the kernel and reboot into it, that's all. There is a new boot-time kernel command line option called exec-shield=, which has 4 values. Each value represents a different level of security: exec-shield=0 - always-disabled exec-shield=1 - default disabled, except binaries that enable it exec-shield=2 - default enabled, except binaries that disable it exec-shield=3 - always-enabled the current patch defaults to 'exec-shield=2'. The security level can also be changed runtime, by writing the level into /proc: echo 0 > /proc/sys/kernel/exec-shield IMPORTANT: security-relevant applications that were started while the exec-shield was disabled, will have an executable stack and will thus have to be restarted if the exec-shield is enabled again. I've also uploaded a modified version of Solar Designer's chstk.c code, which adds the options necessary to change the 'enable non-exec stack' ELF flag: $ ./chstk Usage: ./chstk OPTION FILE... Manage stack area executability flag for binaries -e enable execution permission -E enable non-execution permission -d disable execution permission -D disable non-execution permission -v view current flag state ie. there are two distinct flags, one for forcing an executable stack, one for forcing a non-executable stack. If both flags are zero then the binary will follow the system default. ie. it's possible to use an exec-shield level of 1, and enable the non-exec stack on a per binary basis, by using the 'exec-shield=1' boot option and changing binaries one at a time: ./chstk -E /usr/sbin/sendmail (People migrating production environments to an exec-shield kernel might prefer this variant.) anyway, comments, suggestions and test feedback is welcome. Ingo
From: Davide Libenzi Subject: Re: [Announcement] "Exec Shield", new Linux security feature Date: Fri, 2 May 2003 10:12:56 -0700 (PDT) On Fri, 2 May 2003, Ingo Molnar wrote: > > We are pleased to announce the first publically available source code > release of a new kernel-based security feature called the "Exec Shield", > for Linux/x86. The kernel patch (against 2.4.21-rc1, released under the > GPL/OSL) can be downloaded from: > > http://redhat.com/~mingo/exec-shield/ > > The exec-shield feature provides protection against stack, buffer or > function pointer overflows, and against other types of exploits that rely > on overwriting data structures and/or putting code into those structures. > The patch also makes it harder to pass in and execute the so-called > 'shell-code' of exploits. The patch works transparently, ie. no > application recompilation is necessary. [ very cool stuff ] Ingo, do you want protection against shell code injection ? Have the kernel to assign random stack addresses to processes and they won't be able to guess the stack pointer to place the jump. I use a very simple trick in my code : #define MAX_STKSHIFT 1024 struct thrunner { int (*proc)(void *); void *data; } static int thread_runner(void *data) { struct thrunner *thr = data; alloca(myrand(MAX_STKSHIFT)); return thr->proc(thr->data); } int my_thread_create(int (*proc)(void *), void *data) { struct thrunner *thr; ... thr->proc = proc; thr->data = data; pthread_create(..., thread_runner, thr, ... ); ... } int main(int argc, char *argv[]) { mysrand(); ... } Same thing can be done for non threaded programs : int main(int argc, char *argv[]) { mysrand(); alloca(myrand(MAX_STKSHIFT)); return real_main(argc, argv); } Yes, there's still the possibility that an attacker get lucky ( this get lower increasing MAX_STKSHIFT ) and yes you waste some stack space. But, oh well, it works w/out any kernel modification and it's portable on all systems that have alloca(). - Davide
From: Arjan van de Ven Subject: Re: [Announcement] "Exec Shield", new Linux security feature Date: 02 May 2003 19:18:21 +0200 > Ingo, do you want protection against shell code injection ? Have the > kernel to assign random stack addresses to processes and they won't be > able to guess the stack pointer to place the jump. I use a very simple > trick in my code : stack randomisation is already present in the kernel, in the form of cacheline coloring for HT cpus...
From: Ingo Molnar Subject: Re: [Announcement] "Exec Shield", new Linux security feature Date: Fri, 2 May 2003 13:32:20 -0400 (EDT) On 2 May 2003, Arjan van de Ven wrote: > > Ingo, do you want protection against shell code injection ? Have the > > kernel to assign random stack addresses to processes and they won't be > > able to guess the stack pointer to place the jump. I use a very simple > > trick in my code : > > stack randomisation is already present in the kernel, in the form of > cacheline coloring for HT cpus... we could make it even more prominent than just coloring, to introduce the kind of variability that Davide's approach introduces. It has to be a separate patch obviously. This would further reduce the chance that a remote attack that has to guess the stack would succeed on a random box. Ingo
From: Matthias Andree Subject: Re: [Announcement] "Exec Shield", new Linux security feature Date: Fri, 2 May 2003 19:05:28 +0200 On Fri, 02 May 2003, Ingo Molnar wrote: > We are pleased to announce the first publically available source code > release of a new kernel-based security feature called the "Exec Shield", > for Linux/x86. The kernel patch (against 2.4.21-rc1, released under the > GPL/OSL) can be downloaded from: Am I the only one under the impression that this looks as though this had waited for OpenBSD 3.3 to say "Blbrrrrrrrrp! we're first to have stack protection in the kernel and don't need to hack gcc." (Their W^X isn't enabled on the i386 architecture, but is due (on i386) in 3.4.)
From: Marc-Christian Petersen Subject: Re: [Announcement] "Exec Shield", new Linux security feature Date: Fri, 2 May 2003 19:12:04 +0200 On Friday 02 May 2003 19:05, Matthias Andree wrote: Hi Matthias, > Am I the only one under the impression that this looks as though this > had waited for OpenBSD 3.3 to say "Blbrrrrrrrrp! we're first to have > stack protection in the kernel and don't need to hack gcc." (Their W^X > isn't enabled on the i386 architecture, but is due (on i386) in 3.4.) hehehe ;) Well, they cannot say this even w/o exec shield b/c www.grsecurity.net. :) ciao, Marc
From: Carl-Daniel Hailfinger Subject: Re: [Announcement] "Exec Shield", new Linux security feature Date: Fri, 02 May 2003 23:48:33 +0200 Ingo Molnar wrote: > > Furthermore, the kernel also remaps all PROT_EXEC mappings to the > so-called ASCII-armor area, which on x86 is the addresses 0-16MB. These [snipped] > In the above layout, the highest executable address is 0x01003fff, ie. > every executable address is in the ASCII-armor. If my math is correct, 0x01000000 is 16 MB boundary 0x01003fff is outside the ASCII-armor. Another question: Last time I checked, there were some problems with binary only drivers (to name one, NVidia graphics) and a non-executable stack. Has this been resolved? Regards, Carl-Daniel -- http://www.hailfinger.org/
From: Ingo Molnar Subject: Re: [Announcement] "Exec Shield", new Linux security feature Date: Sat, 3 May 2003 02:52:21 -0400 (EDT) On Fri, 2 May 2003, Carl-Daniel Hailfinger wrote: > Ingo Molnar wrote: > > > > Furthermore, the kernel also remaps all PROT_EXEC mappings to the > > so-called ASCII-armor area, which on x86 is the addresses 0-16MB. These > [snipped] > > In the above layout, the highest executable address is 0x01003fff, ie. > > every executable address is in the ASCII-armor. > > If my math is correct, > 0x01000000 is 16 MB boundary > 0x01003fff is outside the ASCII-armor. the ASCII-armor, more precisely, is between addresses 0x00000000 and 0x0100ffff. Ie. 16 MB + 64K. [in the remaining 64K the \\0 character is in the second byte of the address.] So the 0x01003fff address is still inside the ASCII-armor. > Another question: Last time I checked, there were some problems with > binary only drivers (to name one, NVidia graphics) and a non-executable > stack. Has this been resolved? i'm not using any binary-only drivers, so i have no idea. But as long as they use PROT_EXEC areas for code, they should be safe. Ingo
From: Carl-Daniel Hailfinger Subject: Re: [Announcement] "Exec Shield", new Linux security feature Date: Sat, 03 May 2003 11:56:47 +0200 Ingo Molnar wrote: > On Fri, 2 May 2003, Carl-Daniel Hailfinger wrote: > > >>Ingo Molnar wrote: >> >>>Furthermore, the kernel also remaps all PROT_EXEC mappings to the >>>so-called ASCII-armor area, which on x86 is the addresses 0-16MB. These What happens if the ASCII-armor area is full, i.e. sum(PROT_EXEC sizes) >16MB for a given binary (Mozilla comes to mind)? Does loading fail or does the binary run without any errors, giving the user a false sense of security? >> >>[snipped] >> >>>In the above layout, the highest executable address is 0x01003fff, ie. >>>every executable address is in the ASCII-armor. >> >>If my math is correct, >>0x01000000 is 16 MB boundary >>0x01003fff is outside the ASCII-armor. > > > the ASCII-armor, more precisely, is between addresses 0x00000000 and > 0x0100ffff. Ie. 16 MB + 64K. [in the remaining 64K the \\0 character is in > the second byte of the address.] So the 0x01003fff address is still inside > the ASCII-armor. Thanks. However, that brings me to the next question: 01000000-01004000 r-xp 00000000 16:01 2036120 /home/mingo/cat-lowaddr I was wondering why the executable parts of the binary start at the 16 MB boundary. Is this always the case or just something that happens with cat? In the first case, that would be bad for any binary with a contiguous executable area bigger than 64K. Thanks for answering, Carl-Daniel
From: Arjan van de Ven Subject: Re: [Announcement] "Exec Shield", new Linux security feature Date: 03 May 2003 14:48:35 +0200 On Sat, 2003-05-03 at 11:56, Carl-Daniel Hailfinger wrote: > Ingo Molnar wrote: > > On Fri, 2 May 2003, Carl-Daniel Hailfinger wrote: > > > > > >>Ingo Molnar wrote: > >> > >>>Furthermore, the kernel also remaps all PROT_EXEC mappings to the > >>>so-called ASCII-armor area, which on x86 is the addresses 0-16MB. These > > What happens if the ASCII-armor area is full, i.e. sum(PROT_EXEC sizes) > >16MB for a given binary (Mozilla comes to mind)? Does loading fail or > does the binary run without any errors, giving the user a false sense of > security? the binary will run without errors. And all the libs are still below the main binary (the space for that is much bigger, like 128Mb) so the executable limit is still the end of the main binary. > > > the ASCII-armor, more precisely, is between addresses 0x00000000 and > > 0x0100ffff. Ie. 16 MB + 64K. [in the remaining 64K the \\0 character is in > > the second byte of the address.] So the 0x01003fff address is still inside > > the ASCII-armor. > > Thanks. However, that brings me to the next question: > > 01000000-01004000 r-xp 00000000 16:01 2036120 /home/mingo/cat-lowaddr > > I was wondering why the executable parts of the binary start at the 16 > MB boundary. Is this always the case or just something that happens with > cat? In the first case, that would be bad for any binary with a > contiguous executable area bigger than 64K. the start address of the binary is determined by ld at link time. This cat binary was forced to go at exactly this address. The patch to binutils in Ingo's directory will add the linker option to move apps in this area; it will actually use a lower address than 01000000 to allow for bigger binaries. Obviously this 16Mb zone won't fit all apps, but daemons like sendmail and sshd etc all just fit.
cut off
Looks like the implementation description is cut off mid-stream.
Re: cut off
The given website contains a file ANNOUNCE-exec-shield with the full text.
follow the link...
and read the file ANNOUNCE-exec-shield
re: cut off
Ack - it's fixed.
(At some point it got terminated on a '\0')
What about kernel 2.5.* and beyond?
Does the new development kernel already have equivalent protection?
Re: What about kernel 2.5.* and beyond?
No. Probably won't have for a while, either.
Works, but...
I've tried the patch. The result:
What is work with it? ADSL connection, X, gkrellm, Opera, Xchat, MPlayer, Abiword, OpenOffice.org, Gimp, Apache, Bind, SSH, Return to Castle Wolfenstein: Enemy Territory
What is not work? Mozilla, Evolution, any Java application, becasue the Java VM not work, UT2003, Duke Nukem 3D, Xmms, GNOME progz, Galeon, MySQL
Work?
it is work
Works, but...
Hmm, I don't have any problems running Mozilla or Xmms, but Mplayer crashes if I try to change volume level in module: key_events
The Linux syndrome - patching the patches
This is another pathetic attempt of "patching the patches", creating a mediocre interim solution that does halfway work and halfway destroys other things, just because nobody wants to implement the "big solution" like OpenBSD tries to do with OpenBSD 3.4.
That's the Linux way of doing things...
Troll bait
What you're missing is that in this case (a crappy architecture with no discrete executable-permissions control on memory), there's no Big Solution*. About all we can do for x86 is an ugly hack, and every approach tends to have major drawbacks in some area.
Besides which, I doubt this is even a final implementation. We're just witnessing an interesting branch of development here.
If you want a real solution for the problem, you generally have to step outside the x86 world--i.e. run Linux+GRSecurity on Alpha (where PaX features are supported), or run Solaris 9 with buffer-overflow protection+performance hit, or... (etc. etc.)
*(Yes, I know the real solution would be for all software to be bug-free.)
equivalent... what u can do and what u cant do
yeah, u cant fix the hardware problem directly in your software / kernel...
but software is "ever" equivalent to hardware...
so what u can do (for example) is... put on a virtual machine (emulate another machine with the capabilities and specs u need)... and run your software in this machine... and the machine you create does have this kind of protection your real hardware doesnt give u...
but such a machine would be slow... and all u gain is a non-executeable stack or such thing... what it can not do is to protect the programmer for doing mistakes... and there is of course a lot more than buffer overflow... and remember! end-sollutions do not exist, never.
that linux patch is crap indeed... read linus t., he only needs very few words to proof this is not realy a sollution at all... and nothing is more annoying that to believe to be secure while u aint secure at all...
and i dont think openbsd will will be our final destination.. sure the people are hard working on security... thats what openbsd is all about... but all these chroot / jail / securelevel stuff and such addons are just another closed door, while the attacker is in your house yet, fully armed...! just read the prack article about smashing the openbsd kernel stack...
Eugene
Did you even know what this is about?
If you don't know what the patch does, what it does, how it does it, and where it is all going you shouldn't make comments like this. If you know Linus a little, he always has his own strong opinions about things... they are not nescesarily right/true, just his word is the law. Secondly... it is a software problem, overflows.
The patch implements a sollution to a problem which exists, it isn't tidy but there is just no tidy sollution to this. PAX and ExecShield both use tricks to enforce PROT_EXEC, one better then the other ofcourse.
Mergability is NOT an issue with this kind of work, I can't see any of this work getting merged in any mainline kernel just because it tends to break things, and disabled by default is not really a sollution either... Redhat might decide to do so ofcourse, probably some advanced server distro... but what do I know.
As mentioned before PAX has already implemented to where this is going... If you check the new C5 patch you will see Mingo implemented some randomisation in the stack and mmap...
OpenBSD 3.4
Since part of the problem is x86's funky memory scheme, I'm curious to see how OpenBSD 3.4 implements this of x86. Will it be any more effective or elegant than this Linux exec-shield?
How things should be done
If you want to see how things SHOULD be done, you need to look at PaX.
http://pageexec.virtualave.net/docs
If you read the above documentation, you will see how all these other implementations are missing the "big picture."
It's surprising that all these newcomers are getting press for their half-baked implementations of ideas that have already been implemented for years. (and the newcomers don't like to point out that such previous work exists, since they know (to some extent) that their implementations are clearly inferior).
How posts should be done
Oh, please, do troll some more. Marc-Christian Petersen, in the article above, noted that even OpenBSD's efforts postdated grsecurity, of which PaX claims to be a part. I didn't see Molnar protesting this claim on behalf of PaX/grsecurity, and I also see PaX credits several other projects for some of their work.
What's your problem?
OpenBSD 3.4 and Exec Shield
they pretty much do the same thing, as far as the kernel part is concerned: first, they keep the code/data/stack segments all 0 based but apply a per task (address space) dynamic limit on the code one. effectively all mappings above this limit will be non-executable. the limit is tracked throughout the lifetime of the process (mmap/mprotect can change it). OpenBSD also changes userland to accomodate this new address space layout by relinking all ELF files (main executable + libs) so that their code/data segments are separated by 1GB and hence the data will be mapped high enough in the address space to become non-executable. on the other hand Exec Shield tries to keep these file mappings in the 'ascii armor' area, that is, where the high byte of the address has a 0 in it, in the hope the ascii string based overflows will be hard to exploit this way.
ascii armor
this may be a stupid question...but can somebody tell me how is the ascii armor enforced? what if I write zeros or random bytes into the armored region? would that cause a page fault? is ascii armor some sort of flag you specify for a page table entry? and is this an x86 specific thing?
ascii armor
'ascii armor' is not about what you can write into the armored region but that you cannot (well, sort of) spoof addresses in there in your exploit payload - or so goes the theory. 'ascii armor' is a memory region defined by 0x00000000-0x00ffffff on 32 bit archs (like i386). notice that every address in this region has a 0 the high byte, so when you write your textbook buffer overflow exploit, you will have to stuff in a 0 byte into the payload and that will also terminate ascii string operations (one of which is presumably the culprit in the overflow in the first place). now this alone doesn't mean much, but when you consider that the stack (where presumably the overflowed buffer is) is non-executable (along with the heap, more or less), then you realize that your textbook exploit technique won't work directly (i.e., returning directly to the payload on the stack), so you will have to resort to something called the 'return to libc' style (check some Phrack articles on the topic). this exploit technique requires that you return to already existing code in the task's address space - this is where 'ascii armor' kicks in as all such code is supposed to be found there (not always true, but you get the idea). this is still not a big deal as i386 is little endian, that is, when you overflow your stack buffer (from lower to higher addresses) and overwrite the saved EIP value, you can easily have the string operation put the terminating 0 at the last byte of the saved EIP and hence you'd still be able to return into the 'ascii armor' area. what you won't be able to do however is pass arguments to the function you return to since those would come after the terminating 0... ooops. now, this is the thinking that underlies Exec Shield but unfortunately reality is different.
1. statically linked executables are not protected at all (unless someone relinks them as well to the base of 0x00110000 or so).
2. there's no guarantee that a copy of the exploit payload cannot be found on the heap and that the heap is non-executable (e.g., Linuxthreads creates executable thread stacks by default and in the ES scheme that would raise the executable region limit high enough that all the heap would suddenly become executable).
3. there's no guarantee that the stack layout in any given exploit situation doesn't already hold the proper arguments needed for the attack (be that a simple invocation of system() or others) in which case 'ascii armor' doesn't matter at all.
4. there's nothing to prevent a return into the *middle* of some function (or even executable data, as all the .data sections of mapped libraries are still executable) and if the current CPU registers hold proper values already, one can simply bypass the function epilogue code and have a successful exploit.
5. if the overflowed function was compiled with the frame pointer enabled (EBP register on i386), then one can also control the value of it (as the caller's saved EBP is below the saved EIP) and that combined with the 'return into the middle' technique allows even more control over the passed arguments (EBP need not point to the stack at all).
ascii armor
thanks for your clarification. It all make sense now. I got confused earlier because I thought the contents of 0-16MB was in ascii armor format.
actually........
Just to be pedandtic - the first address that doesn't have a 0 byte in it is 0x01010101 which is 16 MB + 64 KB + 256 bytes + 1 byte.
Re: [Announcement] "Exec Shield", new Linux security feature
Well,
"[...] The patch also makes it harder to pass in and execute the so-called 'shell-code' of exploits. The patch works transparently, ie. no application recompilation is necessary."
It seems that you need recompilation for ET_EXEC randomization.
(not randomiz only the mmaped() aread but the main binary).
As you said the sendmail vuln was a ASCII Only exploitation, and the exploit is still possible. Mine use partial overwrite of the MciCache pointer, and even against randomization it will work since MciCache is pointing already on the heap. I just have to done a little of heap filling the put the fake Mci ** at the rigth place.
So,
my second question is, is the "ascii armor" always at same address ?
(same range for each -recompiled- binary ?)
Thanks
--
sauron
> It seems that you need reco
> It seems that you need recompilation for ET_EXEC randomization.
correct (more precisely, relinking, but that in practice means
recompilation as well).
> is the "ascii armor" always at same address ?
not sure what you mean here... the 'ascii armor' region is independent
of any app, so it's always the 'same'.
The patch implements a
The patch implements a sollution to a problem which exists, it isn't tidy but there is just no tidy sollution to this. PAX and ExecShield both use tricks to enforce PROT_EXEC, one better then the other ofcourse. Muhabbet mirc sohbet Mergability is NOT an issue with this kind of work, I can't see any of this work getting merged in any mainline kernel just because it tends to break things, and disabled by default is not really a sollution either... Redhat might decide to do so ofcourse, probably some advanced server distro... but what do I know. As mentioned before PAX has already implemented to where this is going... If you check the new C5 patch you will see Mingo implemented some randomisation in the stack and mmap...