Boston Linux & Unix (BLU) Home | Calendar | Mail Lists | List Archives | Desktop SIG | Hardware Hacking SIG
Wiki | Flickr | PicasaWeb | Video | Maps & Directions | Installfests | Keysignings
Linux Cafe | Meeting Notes | Blog | Linux Links | Bling | About BLU

BLU Discuss list archive


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

CERT Advisory CA-2001-16



| Rookie question:  How is it possible for a buffer overflow to allow
| access?  Does the overflow automatically provide a shell?  Or does it put
| the process in some debugging mode with remote privileges?

Simple (;-). A program consists of a mixture of code and data chunks,
and  it's  fairly  common  for  linkers  to intermix these in what is
essentially a random order.  So a program's layout in memory may look
something like:

    code1   data1      code2    data2 code3   data3
...|_______|__________|________|_____|_______|______|...

The code chunks are functions; the data chunks correspond  to  global
or static variables, typically belonging to the adjacent code chunks.
In cases like this, if the program were to copy more bytes  into  the
data2  chunk that there was space for, it would overwrite the initial
portion of code3.  Then the next time that code3 is executed, its new
value would be run.

If this were just an ordinary data overwrite due to  a  program  bug,
the  garbaged  code3  chunk  would probably just bomb instantly, most
likely with an illegal instruction or a memory fault.   If  the  data
written  into  data2 were to contain valid machine code, then the new
stuff in code3 wouldn't be junk, but would be the  exploiter's  code,
and  it  would  run with whatever permissions the process happened to
have at the time.

The most common exploitable situation is a  program  that  calls  the
gets() routine.  If you check with `man gets`, you'll see that it has
only a char* pointer to the place to put the next line of input,  and
no  way  to give the size.  So gets() overwrites as much memory as it
needs, until a newline is encountered.  This was a major  mistake  in
the  original C library, which has been cast in concrete by the POSIX
standard.  Its use is usually a mistake, since  the  program  has  no
defense  against input with a very long line.  As long as there is no
newline in my code, I can send a big chunk of code  to  the  process,
and gets() will happily overwrite memory with all of it.

This sort of exploit  doesn't  work  on  all  hardware  or  with  all
linkers.   It's  sometimes  possible to segregate the code chunks and
make them read-only, which prevents them from being overwritten.  But
not  all  hardware  allows  this,  and  even when it does, the linker
doesn't always do it correctly.  In such cases, a bit of analysis  of
the  object  file  may  turn up examples of input buffers immediately
followed by code chunks.  A bit of testing will determine whether the
program  has  a  proper bounds check on input to the buffer.  If not,
then a carefully designed input file can contain just  enough  filler
text  to  fill  the  input buffer, followed by code that will be read
into the code chunk.  It isn't easy, but it's possible.

-
Subcription/unsubscription/info requests: send e-mail with
"subscribe", "unsubscribe", or "info" on the first line of the
message body to discuss-request at blu.org (Subject line is ignored).




BLU is a member of BostonUserGroups
BLU is a member of BostonUserGroups
We also thank MIT for the use of their facilities.

Valid HTML 4.01! Valid CSS!



Boston Linux & Unix / webmaster@blu.org