NODE 00901adcnetscape bug
tomw@orac.engr.sgi.com (Tom Weinstein)Thu, 21 Sep 95 15:42:57 PDT
In article <DF8qC9.4Cw@sgi.sgi.com>, "Vladimir Z. Nuri" <vznuri@netcom.com> writes:
> P.M. notes that anywhere there is a data-driven buffer overflow (which
> he suspects are all over netscape) he can get code to execute anything
> he wants. this reminds me of the
> Morris internet worm that ran exactly the same way. it used a
> bug in the finger demon that caused a string buffer overwrite
> (via strcpy, instead of strncpy) to execute customized code.
> my question: I have not seen the specifics of how this works. does
> this require specialized knowledge of the native machine language on the
> host machine? or is it just used to cause something like a core dump
> to get a command line or something like that?
I question the accuracy of this. The fingerd bug was that a string in
the static data area was read in with gets which could be overflowed.
At some point in memory after this input buffer was the string constant
that stored the name of the finger command. What the Morris work did
was to overflow the input buffer and replace the string constant
"finger" with "csh". When fingerd then exec'ed the command, that gave
you a shell running on the machine.
While it is certainly true that you can stomp on memory in static
buffers, it's not clear that you can execute whatever code you insert
there. If the buffer happens to be allocated off the stack (and the
stack grows down) then you can modify the return address. Of course,
you have to know the address of whatever code you want to execute. And
that code has to do something useful. Presumably, if there are two
bugs, one which lets you write over a static buffer and one for a buffer
allocated from the stack, then you could execute code of your choosing.
Of course, that also assumes that you can execute from the data area
which is not always true.
--
Sure we spend a lot of money, but that doesn't mean | Tom Weinstein
we *do* anything. -- Washington DC motto | tomw@engr.sgi.com
NODE 63e0894dRe: netscape bug
Bill Sommerfeld <sommerfeld@orchard.medford.ma.us>Thu, 21 Sep 95 19:19:20 PDT
> I question the accuracy of this. The fingerd bug was that a string in
> the static data area was read in with gets which could be overflowed.
> At some point in memory after this input buffer was the string constant
> that stored the name of the finger command. What the Morris work did
> was to overflow the input buffer and replace the string constant
> "finger" with "csh". When fingerd then exec'ed the command, that gave
> you a shell running on the machine.
Nope, that wasn't it, either.
See the Eichin/Rochlis "tour of the worm" paper.
I was visiting friends at MIT the night the worm hit. After receiving
some confused and unspecific reports that the worm was getting in
through fingerd, I had a flash of insight as to how that might happen;
as it turned out, this insight was correct, and shortly thereafter, I
had reproduced a benign form of the fingerd attack. As implemented by
the worm, it only worked on vaxes, but it could have worked on other
systems.
The buffer in question was on the stack, not in static storage.
The attacker wrote a long sequence of NOP's, followed by machine
instructions which implemented the equivalent of exec("/bin/sh"),
followed by the approximate stack address of the stack buffer; the
last address was at the right place to overwrite the saved PC field in
the stack frame. When the routine "returned", it actually branched
into the runway of NOP's, and then exec'ed "/bin/sh".
Note that the actual stack address varied, as environment variables
(which tend to vary from installation to installation) are located at
the top of the stack.
As it turned out, the attack did not work on most Athena systems,
because the athena /etc/rc complex wound up using a large number of
environment variables which pushed the location of the stack frame in
question out of the range where the attack would have worked.
- Bill
NODE e37b3c29Re: netscape bug
"Perry E. Metzger" <perry@piermont.com>Thu, 21 Sep 95 21:43:51 PDT
Tom Weinstein writes:
> While it is certainly true that you can stomp on memory in static
> buffers, it's not clear that you can execute whatever code you insert
> there. If the buffer happens to be allocated off the stack (and the
> stack grows down) then you can modify the return address. Of course,
> you have to know the address of whatever code you want to execute.
Lets say, Mr. Weinstein, that you shove some code onto the stack along
with the return address, and the address happens to be the code.
If you don't believe it can be done, its easy enough to demonstrate it
on your machines, which I believe suffer from the syslog(3) bug, which
your company hasn't patched so far as I know, and which afflicts the
Sendmail daemons you ship with your machines. See the recent 8lgm bug
report if you want details.
> Of course, that also assumes that you can execute from the data area
> which is not always true.
Its usually true on modern machines -- its very difficult to rig
things otherwise given the way that lots of the dynamic loading works
these days.
Perry
NODE ba6ec4b9Re: netscape bug
Ray Cromwell <rjc@clark.net>Thu, 21 Sep 95 22:12:06 PDT
Maybe I'm missing something here, but I don't see it. While it is easy
to use the "overwrite buffer and stomp on stack" method to execute code
for programs written as so
void foo(char* inputdata)
{
char blah[X];
write_to_buffer_without_knowing_length(inputdata, blah);
}
How would you do it for a program rewritten as
void foo(char* intputdata)
{
char* blah;
blah=PMalloc(X);
write_to_buffer_without_knowing_length(inputdata, blah);
}
Where PMalloc acts like malloc, but from a separate heap. Two
other conditions further hold. All variables in this separate heap
are viewed as "tainted" since they came from user input, and can not
be used as arguments to system(), popen(), fopen(), etc.
Given this, I don't see how it is possible to cause code to be executed.
For one thing, you can't modify the stack. Secondly, since buffers
can't be used as arguments for i/o calls, overwriting nearby buffers like
char *program_path = "auxillary_program" to "/bin/csh" won't do you any
good. (note: a pointer variable should never point to data on the stack
anyway. I'm glad Java eliminated stack data. Pointers to stack data
are the source of numerous bugs in C. There is a minor performance gain
to having the compiler generate the stack allocation rather than
call malloc(), but it's not worth it. Stack data has the benefit that
it is automatically deallocated upon function return. My answer is
to simply use C++ to achieve this with dynamically allocated resources)
I for one, never use scanf(), gets(), or anything that doesn't know the
size of the destination storage. It's plain stupid. I was tutoring
a student today who had allocated a 20-byte buffer on the stack and
used scanf to ask for a filename. Sheesh.
One thing that should set off alarm bells immediately whenever your
coding is a fixed size buffer justified with the idea "no one could
ever use more than Y resources." Yeah, no one could ever use more
than 11 character file names. 640K ram. 32-bit IP address space. etc, etc.
If not for security, then for simple future flexability.
-Ray
NODE 570ef462Re: netscape bug
tomw@orac.engr.sgi.com (Tom Weinstein)Thu, 21 Sep 95 22:33:41 PDT
In article <199509220443.AAA02254@frankenstein.piermont.com>, "Perry E. Metzger" <perry@piermont.com> writes:
> Tom Weinstein writes:
>> While it is certainly true that you can stomp on memory in static
>> buffers, it's not clear that you can execute whatever code you insert
>> there. If the buffer happens to be allocated off the stack (and the
>> stack grows down) then you can modify the return address. Of course,
>> you have to know the address of whatever code you want to execute.
> Lets say, Mr. Weinstein, that you shove some code onto the stack along
> with the return address, and the address happens to be the code.
I never disputed that it could be done, I was just uncertain as to how
easy it would be. As has been pointed out, it's not nearly as hard as I
thought, assuming you can execute in the stack.
> If you don't believe it can be done, its easy enough to demonstrate it
> on your machines, which I believe suffer from the syslog(3) bug, which
> your company hasn't patched so far as I know, and which afflicts the
> Sendmail daemons you ship with your machines. See the recent 8lgm bug
> report if you want details.
Hmm, could you explain how to exercise this bug? Perhaps a sample
program?
>> Of course, that also assumes that you can execute from the data area
>> which is not always true.
> Its usually true on modern machines -- its very difficult to rig
> things otherwise given the way that lots of the dynamic loading works
> these days.
True.
--
Sure we spend a lot of money, but that doesn't mean | Tom Weinstein
we *do* anything. -- Washington DC motto | tomw@engr.sgi.com
NODE 26a40e54Re: netscape bug
"Perry E. Metzger" <perry@piermont.com>Thu, 21 Sep 95 22:38:08 PDT
Tom Weinstein writes:
> > Lets say, Mr. Weinstein, that you shove some code onto the stack along
> > with the return address, and the address happens to be the code.
>
> I never disputed that it could be done, I was just uncertain as to how
> easy it would be.
Its pretty obvious.
> > If you don't believe it can be done, its easy enough to demonstrate it
> > on your machines, which I believe suffer from the syslog(3) bug, which
> > your company hasn't patched so far as I know, and which afflicts the
> > Sendmail daemons you ship with your machines. See the recent 8lgm bug
> > report if you want details.
>
> Hmm, could you explain how to exercise this bug? Perhaps a sample
> program?
I can tell you in general terms -- I don't write MIPS assembler
myself. However, I will point out to you that you use an ancient
Sendmail, and that it uses syslog(3) on user produced data, and that
syslog uses a static buffer. Trick sendmail into logging something
very big, and you can do what you like. The 8lgm people wrote a demo
for Sparc as a proof of concept.
Perry