Bugtraq mailing list archives

Re: Ray Cromwell: Another Netscape Bug (and possible security


From: mengel () dcdmwm fnal gov (Marc W. Mengel)
Date: Wed, 27 Sep 1995 14:33:54 CDT


In <199509270932.KAA01892 () meteo cling gu se>  you write:

Hey folks, I need to know about this 'stack overwriting thing'
thet is so lively discussed. As I understand it (and correct me
if I'm wrong), the point is to pass in data to a non-bound
checking routine (like syslog), and make it so constructed
that it 'rewrites' some parameters on the stack.
Subsequent routines will then pop these phoney params and
off we go...
Am I right? Can anybody provide me with more detailed info
and perhaps some harmless example (please please please!!!)

Well, since this seems like a question that lots of people ask, I'll
give a high level description of how this works; there are several
people working on exploits for explicit programs that can be examined.

For those that are about to flame me for answering this on bugtraq, I'm
hoping this will reduce the number of other folks asking basically this
question.

For a simple example, consider a C routine like:

full_of_holes(int x) {
        char buf[2];

        gets(buf);
        return atoi(buf) + x;
}

When full_of_holes is called, the value for x is pushed on the stack
and a subroutine call is made, which pushes a return address, etc.
on the stack.  Then a two byte area is allocated, and the address of
it is pushed on the stack, and we call fgets. The stack now looks
like this (assuming the stack pointer was at location 1000 when we
called full_of_holes
        ffff1000:  5    value of x
               ffff1004:  00001234      return address for caller of full_of_holes
        ffff1008:  ffff1010     other function call stuff
        ffff100C: 0     buf[0], buf[1] two bytes of pad
        ffff1010: 100C  address of buf[0]
        ffff1014  00004567      return address for caller of gets
               ffff1018: ffff1010       other function call stuff
               ffff101C: 1      first local variable for gets.
        ....

Now lets say for the sake of argument that gets is about to read a line
with more than two characters on it.  In particular lets assume it
some magic bytes such that when we have read it into buf, the stack now
looks like:
        ffff1000:  5    value of x
               ffff1004:  00001234      return address for caller of full_of_holes
        ffff1008:  ffff1010     other function call stuff
        ffff100C:  deadbeef     buf[0], buf[1] two bytes of pad
        ffff1010: deadbeef      address of buf[0]
        ffff1014  ffff1018      return address for caller of gets
               ffff1018: xxxxxxxx       other function call stuff
               ffff101C: xxxxxxxx       first local variable for gets.
        ....
where the data read by gets was the "deadbeefdeadbeefffff1010xxxxxxxxxxxxxxxx..
."
(in hex), and xxxxxx.... is some happy executable code on this hardware.
we now go to return from gets, which grabs address ffff1018 off the stack,
and shoves it in the program counter.  You then proceed to execute the
code xxxxx....

Marc



Current thread: