The first thing I'd like to say is to thank him(?) for this article.
Clever and thought-provoking.
The next thing I'd like to say is to observe the elaborateness
involved. An attack such as described involves quite a lot of
investigation on the target system and several addresses that must be
gotten exactly right and must not happen to contain NUL bytes. This
means that - even though it is not a perfect defense - Solar Designer's
patch *does* harden a system significantly and is still worth applying
(at least for systems for which it ever was considered worth applying;
all its downsides are still there, of course). (In all fairness, Rafal
did realize and mention the precision required.)
> Section X. Any solutions - continued
> Well, if
> a) we can protect data segments from being executed
> b) we force LD_BIND_NOW - like dynamic linking, which enables us to
> mprotect GOT non-writable
> both exploits will fail.
True. And if you're willing to pay the price of two more syscalls per
dynamic-linker resolution, you can get lazy binding *and* have all the
security benefits of (b). All you need is for the dynamic linker to
leave the GOT read-only, then use mprotect to re-protect it just before
and after it snaps the pointer to the real routine. This would make it
(almost) impossible to attack through the GOT, since it's not
modifiable except for a very brief time deep within the guts of the
dynamic linker. (Sure, if you can get your code executed, you can
re-mprotect it - but if you can do that, you're home free anyway.)
> The best solution would be to mmap text segment ( accompanied by
> PLT and GOT ) under 16MB boundary. But it's impossible, right ?
> Code of applications is not position independent.
This would mean a linker change, so that user-land programs get linked
with the text segment in low memory. If the linker is careful to link
the PLT and GOT early (eg, right after crt0), you can ensure *it* is
below 16M even if the text segment is over 16M.
An idea which should stop these scribbling attacks cold is this: put
guard bytes above and below the return address on the stack - and use
0x00 as the guard bytes. Then the function epilogue/return code checks
for these 0x00 bytes and if it doesn't find them it does something
appropriate for a garbaged return address - a deliberate segfault,
perhaps, or a halt-cpu instruction (which certainly ought to be
sufficiently illegal for user-land code!). The point, of course, is
that you would have to find a way to overwrite the return address
without disturbing the NULs, which is very hard when using routines
like strcpy or sprintf, the favorites of smash-the-stack attacks, since
they stop at NULs.
Does anyone know of any common routine which (a) has an unlimited-size
interface and (b) is capable of writing user-supplied data containing
NULs into the target area? (Even if such a routine is found, merely
getting the exploit string to it intact is nontrivial, since NULs also
cannot be present in things like environment variables.)
der Mouse
mouse@rodents.montreal.qc.ca
7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B