buffer overflows 
Author Message
 buffer overflows

do buffer overflows only happen in HLLs? If not, how can an asm program be
prone to a buffer overflow?


Tue, 19 Nov 2002 03:00:00 GMT  
 buffer overflows

alt.lang.asm:

Quote:
> do buffer overflows only happen in HLLs? If not, how can an asm program be
> prone to a buffer overflow?

By calling a function with a buffer that's too small, or specifying
the length incorrectly.

Most operating systems have a system call to read a number of bytes
from a file.  Suppose you define a buffer of 20 bytes, then call the
OS function to read 256 bytes into this buffer?

Jack Klein
--
Home: http://jackklein.home.att.net



Wed, 20 Nov 2002 03:00:00 GMT  
 buffer overflows

Quote:

>By calling a function with a buffer that's too small, or specifying
>the length incorrectly.

>Most operating systems have a system call to read a number of bytes
>from a file.  Suppose you define a buffer of 20 bytes, then call the
>OS function to read 256 bytes into this buffer?

Okay, in your example, there would be 236 bytes extra. It may be that this 236
bytes are code, but how can this code actually result in being executed?
Wouldn't it either be on the stack or in a data section? Wouldn't the program
have to explicitly be modified to execute that code from the data section?


Wed, 20 Nov 2002 03:00:00 GMT  
 buffer overflows

alt.lang.asm:

Quote:


> >By calling a function with a buffer that's too small, or specifying
> >the length incorrectly.

> >Most operating systems have a system call to read a number of bytes
> >from a file.  Suppose you define a buffer of 20 bytes, then call the
> >OS function to read 256 bytes into this buffer?

> Okay, in your example, there would be 236 bytes extra. It may be that this 236
> bytes are code, but how can this code actually result in being executed?
> Wouldn't it either be on the stack or in a data section? Wouldn't the program
> have to explicitly be modified to execute that code from the data section?

In the first place, all you asked about were buffer overflows, and a
buffer overflow means putting more information into a buffer than it
can hold, so memory outside the buffer is overwritten.  It has nothing
to do with what happens afterward, that is a consequence of the buffer
overflow.  In my example whether or not any of the overflow data ever
executes as code has nothing to do with the fact of the overflow.

What is a "stack" or a "data segment"?  These are terms that refer to
features of a specific architecture, and this is a processor and
system independent group about general assembly language topics.

Finally you seem to be asking about how certain types of viruses work,
and I am not in the habit of describing how to make a virus in a
public newsgroup for the whole world to see, nor of giving that kind
of information to strangers who might try to do damage with it.

Jack Klein
--
Home: http://jackklein.home.att.net



Wed, 20 Nov 2002 03:00:00 GMT  
 buffer overflows

Quote:

> Finally you seem to be asking about how certain types of viruses work,
> and I am not in the habit of describing how to make a virus in a
> public newsgroup for the whole world to see, nor of giving that kind
> of information to strangers who might try to do damage with it.

I do not share your habit or opinion.  I firmly believe that
security-by-obscurity is very dangerous.  So I will describe
what I know about buffer overflows:

Stack buffer overflows are extremely dangerous because they allow
the stack and most particularly the return address to become
corrupted.  What typically happens is that in a `c` subfunction,
some buffer space is allocated as a local variable.  Most/all
compilers will put all locals on the stack by decrementing ESP.  

Later, some `read` function will be called to read user data
into this stack buffer.  As usual in `c`, it is the programmers
responsibility to ensure that the receiving buffer is big enough
to accomodate the incoming data.  Only a malicious cracker will
supply more data that is actually exploit code.  

It will be overlong so that it clobbers previously allocated
locals and  overwrites the return address to point at itself!  
The `read` function will happily load it.  When the `c` function
tries to process it, it will probably not recognize the code
as valid data and try to return an error.  

But the moment it executes a `ret` instruction, it jumps to the
buffer code because the return address has been overwritten!
{*filter*} ... very {*filter*}.

These exploits require some of expertise to write plus access
to the binary to be exploited and a good de{*filter*}.  Access to
source code is not necessary, so free software [open source]
is not more vulnerable.

The correct defense against stack buffer overflows is correct
coding practice.  IMHO, sticking fundamentally variable buffers
on the stack is wasteful, dangerous and just asking for trouble.
Either a fixed-lenght read should be done, or the variable
read go to a buffer in .data or .bss where  an overflow will
clobber only data, but not corrupt the execution path.  

The easiest fix is to declare buffers global or static which
will put them in .data or .bss .  Unfortunately, modern pgming
practice is to avoid globals & statics.

Perhaps there is an elegant solution at the Operating System
level if a range of data/pages can be marked "do not execute"
in much the same way as code pages are marked "do not write".
But this will depend on having these features on silicon.
I will have to check if the popular x86 has this.  

At the very least, the OS could check for a read-only return
address since the exploit code is likely to make syscalls.

-- Robert



Wed, 20 Nov 2002 03:00:00 GMT  
 buffer overflows

Quote:
> do buffer overflows only happen in HLLs?

Hell no!  They can happen in any program that doesn't do buffer-checking.
This includes C, C++ and assembly.

Quote:
> If not, how can an asm program be prone to a buffer overflow?

Simply if it doesn't check.  I did it myself just this morning.  I wrote
an encryption program that converts one buffer into encrypted
format, then puts it into another buffer.  I made both buffers the same
size, but the encrypted material is about twice as long as the
unencrypted.  I blew the output buffer and my program crashed.

Richard Cavell.



Thu, 21 Nov 2002 03:00:00 GMT  
 buffer overflows

Quote:

>  I firmly believe that
> security-by-obscurity is very dangerous.

Good point. Hopefully, the information you've provided will do more good
reminding non-malicious programmers to avoid these vulnerabilities than
any harm done by enlightening anyone with malicious intent.

Quote:
> Either a fixed-lenght read should be done, or the variable
> read go to a buffer in .data or .bss where  an overflow will
> clobber only data, but not corrupt the execution path.

The latter solution eliminates the vulnerability, but leaves the
overflow. Are there situations where we *must* accept a variable-length
read?

Thanks,
Frank



Thu, 21 Nov 2002 03:00:00 GMT  
 buffer overflows

Quote:


> >  I firmly believe that
> > security-by-obscurity is very dangerous.
> Good point. Hopefully, the information you've provided will do more good
> reminding non-malicious programmers to avoid these vulnerabilities than
> any harm done by enlightening anyone with malicious intent.

I think those with malicious intent are unfortunately already too
well informed. This isn't new.  For a nice, old discussion see:
http://www.deter.com/unix/papers/treatise_locks.html

Quote:
> > Either a fixed-lenght read should be done, or the variable
> > read go to a buffer in .data or .bss where  an overflow will
> > clobber only data, but not corrupt the execution path.

> The latter solution eliminates the vulnerability, but leaves the
> overflow. Are there situations where we *must* accept a variable-length
> read?

Sure.  How about a communications or keyboard session?  Notice
that these use ring buffers and overflow by dropping chars, not
clobbering nearby data.  But for a one-short variable read, there
really is no such thing.  The buffer is pre-allocated, and must be
of fixed size.

-- Robert



Thu, 21 Nov 2002 03:00:00 GMT  
 buffer overflows
Frank Kotler wrote in small part:

Quote:

> Consider this useless little program that gets input from stdin, puts it
> in a buffer, and spits it out when the user hits "enter". It will
> quickly overrun its buffer, but since there's no other data to clobber,
> it doesn't do any harm. It works fine. Sure there's an error, but it
> isn't "dangerous" ... is it?

> ; nasm -f bin hackme.asm -o hackme.com
> org 100h
> section .bss
>     buffer resb 5     ; absurdly small buffer[snip]
> This isn't a virus or anything {*filter*}, but it causes some code to execute
> that you didn't intend to execute, when fed to the above program
> "hackme<hackme.dat".

> ; nasm -f bin hackdat.asm -o hackme.dat
> org 12Ch[snip]
> times 0FFFCh - ($-$$) - 12Ch db 0
> dw 12Ch
> db 0Dh

This is actually some fairly clever code, moreso since it shows
an exploit possible from .bss in the "tiny" model that *.COM pgms
live in.  The 64 KB of hackme.dat manages to overwrite the stack.

More often however, the distance from .bss to .stack is around
1 GB that will pagefault, not 64 KB.   The usual exploit happens
much easier because the pgmr/`c` compiler actually has declared
the buffer as local, so it goes on the stack:

fn_entry:   (std `c` prolog)
        push    ebp
        mov     ebp, esp
        sub     esp, size_of_locals
param1  EQU     dword ptr[ebp + 8]
local1  EQU     dword ptr[ebp - 4]
buffer  EQU     byte  ptr[ebp - some_offset]   ; say it ain't so!
        lea     eax, buffer
        push    eax
        push    file_handle
        call    read_foobar

And you get royally hosed.  Try compiling some `c` code
with a local buffer, and cry at the code you get.  Worse,
be afraid that most `c` pgmrs are instructed to maximize
the use of locals, and eschew globals/statics which as you
show, aren't always even safe.  Be very afraid.

Programmers are going to have to either used fixed length
reads, or put their buffers somewhere safe, like on the moon!
.data and .bss might be a close enough approximation on a
pmode 32 bit OS.  The stack is NOT safe.

--  Robert



Thu, 21 Nov 2002 03:00:00 GMT  
 buffer overflows
I've got some more questions about exploiting buffer overflows.

What about buffer exploits that don't actually overflow the buffer?
Isn't it possible that exploit code is included in the buffer and uses a
(dummy) CALL so that it returns and executes the next statement to start
the expoit?

Also what happens to the host process in buffer oveflow exploits? Do
they normally terminate abnormally and are there ways to allow them to
continue instead?

regards,
rhys



Fri, 22 Nov 2002 03:00:00 GMT  
 buffer overflows

Quote:

> This is actually some fairly clever code, moreso since it shows
> an exploit possible from .bss in the "tiny" model that *.COM pgms
> live in.  The 64 KB of hackme.dat manages to overwrite the stack.

Frighteningly easy to cook up!!!

Quote:
> More often however, the distance from .bss to .stack is around
> 1 GB that will pagefault, not 64 KB.   The usual exploit happens
> much easier because the pgmr/`c` compiler actually has declared
> the buffer as local, so it goes on the stack:

> fn_entry:   (std `c` prolog)
>         push    ebp
>         mov     ebp, esp
>         sub     esp, size_of_locals
> param1  EQU     dword ptr[ebp + 8]
> local1  EQU     dword ptr[ebp - 4]
> buffer  EQU     byte  ptr[ebp - some_offset]   ; say it ain't so!
>         lea     eax, buffer
>         push    eax
>         push    file_handle
>         call    read_foobar

> And you get royally hosed.

You sure do. I had no idea this was such a potentially dangerous error.
When I was trying to learn "C", I recall reading "never use 'gets' - use
'fgets' on STDIN instead" - precisely because it has a size limitation.
I always used "gets" anyway, and into a temporary buffer :(. Writing
asm, I'm more aware of avoiding buffer overflows just on "general
principles", but I can see I'm going to have to be even more careful.

Putting the buffer someplace "safe" protects against this particular
attack, but allowing a buffer overflow can still cause trouble. The
better solution, I think, is to not *use* "read_foobar", but instead use
"read_n_foobar" and push a size/length parameter too. If "read_n_foobar"
doesn't exist, we ought to write it!

Would a ring-buffer be an option here? I don't see that something like
"read_foobar" lends itself to that. Don't we have to have access to the
data a byte-at-a-time to implement a ring buffer? If "read_foobar"
really needs to be able to accept an unlimited amount of data
(communications, say) it could be implemented internally to use a ring
buffer - with the risk of "dropping" data - or some mechanism to tell
the "sender" to stop while we clear the buffer. If we allow
"read_foobar" to overrun our buffer, the result is likely to be
unwelcome, even if the stack is out of reach.

Quote:
>  Try compiling some `c` code
> with a local buffer, and cry at the code you get.  Worse,
> be afraid that most `c` pgmrs are instructed to maximize
> the use of locals, and eschew globals/statics which as you
> show, aren't always even safe.  Be very afraid.

This gets back to InfamousX01's question: "C" programs might be *more*
prone to this weakness, but asm programmers *do* need to worry about
both "buffer overflow exploits" and plain "buffer overflows".

Quote:
> Programmers are going to have to either used fixed length
> reads, or put their buffers somewhere safe, like on the moon!
> .data and .bss might be a close enough approximation on a
> pmode 32 bit OS.  The stack is NOT safe.

"segment .moon" - I like that! The stack is not safe, and a ".com" file
is *all* stack, if you look at it that way. Hmmm, if I allocated a
buffer, that would probably be above the stack, wouldn't it? Not that a
".com" file is a likely target for an "exploit"...

Before we give up and say, "I can't avoid buffer overflow, I'll have to
put my buffer someplace safe" I think we ought to put up a heck of a
fight to avoid it in the first place! I know I'm going to be careful,
now that I realize how serious an innocuous looking error can be!

Best,
Frank



Fri, 22 Nov 2002 03:00:00 GMT  
 
 [ 18 post ]  Go to page: [1] [2]

 Relevant Pages 

1. CD 3.1 "Buffer Overflow" in report

2. Clipper 5.01 C3002 Input Buffer Overflow error

3. VO1.c output buffer overflow

4. Serial-Buffer overflow without too much incoming data or bursts on the line

5. VO: output buffer overflow:52600 ??

6. VO 1.0c Output buffer overflow error?

7. want to understand code for buffer overflows

8. Urg,ent, keyboard buffer overflow

9. Buffer overflow issues with NAGware f95 v 4.1

10. Help! Buffer overflow on output

11. bsddb buffer overflow

12. Buffer overflows?

 

 
Powered by phpBB® Forum Software