Differences between current version and predecessor to the previous major change of BufferOverflow.
Other diffs: Previous Revision, Previous Author, or view the Annotated Edit History
Newer page: | version 2 | Last edited on Sunday, March 7, 2004 3:05:08 pm | by AristotlePagaltzis | |
Older page: | version 1 | Last edited on Sunday, March 7, 2004 2:16:13 am | by PerryLorier | Revert |
@@ -1,5 +1,7 @@
-Buffer overflows are
when you read more
data into a buffer than it can hold
, normally
overwriting the data of
whatever the next thing
is in memory.
This has been exploited to great effect in recent years due to sloppy C/C++ coding.
+A BufferOverflow can occurs
when a program copies input
data without checking its length
into a buffer that's too short for the input in question
, overwriting whatever is next
in memory. This has been exploited to great effect in recent years due to sloppy [
C]
/[
C++]
coding.
-The main problem with exploiting buffer overflows is that
the stack
grows "down" (ie, to lower addresses
), and you write to
buffers "upwards" (
towards higher addresses). This means that if
a buffer is stored on
the stack
, then
you can overwrite whatever else is on the stack including the
return address of a function. Thus, normally exploits are set up so when
a function returns it returns
into the address of
the buffer, and then arbitary (
usually malicious)
code can be executed
.
+Because
the [Stack]
grows towards grows lower addresses (
"down"), while
buffers are written
towards higher addresses ("upwards"
), during function calls one of the next things in memory past
a buffer usually
is the address to return to from the call. By carefully chosing the value at the right place of your input data
, you can overwrite this
return address with
a value that points
into the buffer now filled with your input
, thus causing the program to execute whatever data you provided once the function returns. Such input is
usually carefully constructed
malicious code.
-Recently there has been a great deal
of discussion about making
the stack non executable so that
this attack will fail. This however ([IMHO]) is rather pointless
, since you can just set up
the stack in
a way where it runs
a sequence
of libc functions anyway
. Admittidly
you can't do conditionals, but you can make it return into for instance
the beginning
of "system(3)"
with the parameter
"rm -rf /" on the stack where system would expect
it's argument
.
+Because
of the wide applicability of
this attack technique
, it has been studied so thoroughly that construction of exploitative input has become an almost formulaic procedure. The timespan between
the discovery of
a BufferOverflow vulnerability and creation of an exploit is rarely longer than
a day, and often a matter
of only hours
.
+
+An obvious but shortsighted counter is to mark the memory area containing the [Stack] as non-executable. The problem is that even though
you can't do conditionals this way
, the input data could still be constructed to cause execution
of arbitrary functions or a sequence thereof. F.ex, execution could
"return" into
system(3) with "rm -rf /" as a parameter
on the stack. This is only a plump example;
it is conceivable for an attacker to choose other calls so as to eg. gain access to a root shell
.