Re: executable stacks, a few suggetions
Wed, 16 Apr 1997 15:04:29 -0300 (GMT)


> Let's suppose that I can find an indirect call instruction somewhere
> that uses a callee-save register (%ebx, %ebp, %esi, %edi on the x86).

If you actually try searching for these sequences of bytes (I did, and
before receiving your message), you'll find out only some binaries contain
them, while some don't:

# ./search /bin/* /sbin/* /usr/bin/* /usr/sbin/*
ff d3 105/692
ff d5 24/692
ff d6 284/692
ff d7 134/692

The final line shows the number of files containing any of the four. Quite
a high number of files, true (well, not all of them have the bytes in the
loadable image, and not all of them contain the corresponding popl %reg
instruction followed by a ret soon enough, only the functions actually
using a register save and restore it -- however I think most of these 378 do
contain the required stuff).

> Then I smash the stack to put the buffer's address into the stack save
> slot for that register, and smash the return address to point to
> the indirect call instruction.

The vulnerable function itself may not save that register, since it may not
modify it, so you will usually have to find some other function with the
popl %reg, and modify the return address to that popl, supply the value for
the register, and one more return address to point to the call *%reg. A bit
complicated, but possible for about 50% of the files (can't be sure whether
a bit more or a bit less than 50% due to the extra factors I mentioned), as we
can see above.

Another problem -- it is enough to exploit if the vulnerable program puts
some value it receives from the user, before the vulnerable function is
called, to the bss. With such a GPF handler an integer being put this way
is enough, due to the instruction being tiny.

> The only way to fix *that* that I know of is to check that the code
> jumped to really looks like a trampoline, and not exec("/bin/sh").

Not a fix at all, since the code on the stack can be totally specified by
the exploit, and can be made looking like a trampoline.

The only fix that I see is to leave a configurable option to choose between
the GPF handler trampoline autodetection code, and manual stack execution
enabling for each program that needs it, by a header flag for example.

The reason to still leave the GPF stuff also is that it's much easier to
install, still protects in some cases, and makes the exploits more complicated
in others.

Solar Designer