Re: Doubts in shellcode !?

From: srt@nospam.unt.edu
Date: 08/28/02


From: srt@nospam.unt.edu
Date: Wed, 28 Aug 2002 14:52:34 +0000 (UTC)

Nick Maclaren <nmm1@cus.cam.ac.uk> wrote:
> In article <akijli$qj2$1@hermes.acs.unt.edu>, srt@nospam.unt.edu writes:
> |> Nick Maclaren <nmm1@cus.cam.ac.uk> wrote:
> |>
> |> > Did he just? I can see why you got confused. That is one of the
> |> > most stupidly buggy programs I have seen in a long time. It might
> |> > do what he thinks on one compiler, but doesn't even clarify the
> |> > point. A clearer way of writing it (though also not reliable and
> |> > definitely not conforming or portable) is:
> |>
> |> > int main() {
> |> > return (int (*) (void))shellcode;
> |> > }
> |>
> |> That doesn't do the same thing at all... in fact, it doesn't do
> |> anything except exit with a strange error code.

> Oops! Yes. I left out the call, and meant:

> int main() {
> return ((int (*) (void))shellcode)();
> }

Well... that accomplishes the same thing, but works pretty
differently. The compiler actually generates a "call" instruction
there rather than transferring control through the return from main.

The significance is that I imagine "shellcode" is really trying to
demonstrate how a buffer overflow attack works -- you can force the
transfer by manipulating the data on the stack, not by compiling it
into the program.

> |> The key to the original code is that it over-writes the return address
> |> on the stack with a pointer to the shell code, so that instead of
> |> returning to the stub that calls main(), it returns to the "shellcode"
> |> function. The previous frame pointer is at &retorno+1, and the return
> |> address is at &retorno+2. It's really taking advantage of the fact
> |> that there are no memory access checks in C, so you can just go out
> |> and clobber memory that you have no business clobbering....

> That was my point about it being unclear and compiler dependent.
> Even on systems which have falling stacks, keep their return address
> on the bottom of the stack, and all that - you STILL cannot rely on
> the first variable in a function being immediately below that. It
> is extremely common that it isn't.

True -- and in fact, it depends on options with some compilers too.
>From what I remember, MS Visual Studio has an option that helps check
memory problems, and it does this by putting a little "buffer zone"
between the return address and the first variable. Then it can check
to see if the right pattern is still in that area before doing a
return, just to make sure no local pointers got out of control and
wrote outside the current frame. That's not foolproof, of course, but
it's an example of what you say above -- you can't really count on the
return address being there unless you know exactly how the program is
compiled.

-- 
Steve Tate - srt[At]cs.unt.edu | "A computer lets you make more mistakes faster
Dept. of Computer Sciences     | than any invention in human history with the
University of North Texas      | possible exceptions of handguns and tequila."
Denton, TX  76201              |         -- Mitch Ratliffe, April 1992



Relevant Pages

  • Re: made it to page 4 of gforth tutorial
    ... the stack space anyway. ... And there are clearly going to be some platform ... came with an embedded C compiler once. ... like I've written before, if one *really* needs recursion (as I have, ...
    (comp.lang.forth)
  • Re: multiple return values
    ... isn't a first class object. ... which could be on the stack. ... they are managed by the compiler. ... Keeping the memory locations and the entire mechanism shrouded from the ...
    (comp.lang.lisp)
  • Re: Why not auto?
    ... >>> on a system where stack space is limited declaring all local variables ... The compiler is in a perfect position to know which parameters would ... The compiler could also apply such optimisations to automatic ... likely to promote memory reuse and improved caching. ...
    (comp.lang.c)
  • Re: Do buffers always start with the lowest memory address being the first element?
    ... > The C standard does not assume a downward-growing stack, ... > an upward-growing stack. ... C allows but does not require that the array produced ... > machine depends on both the C compiler and the machine. ...
    (comp.lang.c)
  • Re: Really tiny microcontrollers
    ... your compiler should allow you to store them as uint16_t. ... If you have 4K RAM, then a linked list is not a natural solution. ... Although the size of stack entries cannot be lowered, ... STRH R0, ...
    (comp.arch.embedded)