Add content
This commit is contained in:
parent
509935c9cd
commit
a6b265e80e
@ -72,26 +72,58 @@ Heartbleed bug in OpenSSL which allowed dumping secret keys from memory. Out of
|
|||||||
bounds writes are almost always critical and result in code execution
|
bounds writes are almost always critical and result in code execution
|
||||||
vulnerabilities or at least application crashes.
|
vulnerabilities or at least application crashes.
|
||||||
|
|
||||||
% Ever since the first programming languages were designed, security has been a
|
|
||||||
% concern of software developers. With more advanced programming languages, that
|
|
||||||
% did automatic memory management, some classes of errors were fixed. But
|
|
||||||
% languages with unsafe, manual memory management are still in use and power
|
|
||||||
% critical parts of the worlds infrastructure.
|
|
||||||
|
|
||||||
|
|
||||||
\section{Main Part, TODO}\label{ref:main} %TODO!!!!
|
\section{Main Part, TODO}\label{ref:main} %TODO!!!!
|
||||||
|
|
||||||
\subsection{Background}\label{ref:background}
|
\subsection{Background}\label{ref:background}
|
||||||
|
|
||||||
text
|
Exploitation of buffer overflow vulnerabilities almost always works by
|
||||||
|
overriding the return address in the current stack frame, so when the `ret`
|
||||||
|
instruction is executed, an attacker controlled address is moved into the
|
||||||
|
instruction pointer register and the code pointed to by this address is
|
||||||
|
executed. Other ways include overriding addresses in the PLT of a binary so
|
||||||
|
that, if a linked function is called, an attacker controlled function is called
|
||||||
|
instead, or (in C++) overriding the vtable where the pointers to an object's
|
||||||
|
methods are stored.
|
||||||
|
|
||||||
\subsection{Concept and Methods}\label{ref:concept}
|
\subsection{Concept and Methods}\label{ref:concept}
|
||||||
|
|
||||||
\subsubsection{Runtime Bounds Checks}
|
\subsubsection{Runtime Bounds Checks}
|
||||||
|
|
||||||
|
The easiest and maybe single most effective method to prevent buffer overflows
|
||||||
|
is to check, if a write or read operation is out of bounds. This requires
|
||||||
|
storing the size of a buffer together with the pointer to the buffer and check
|
||||||
|
for each read or write in the buffer, if it is in bounds at runtime.
|
||||||
|
|
||||||
\subsubsection{Prevent Overriding Return Address}
|
\subsubsection{Prevent Overriding Return Address}
|
||||||
|
|
||||||
|
Since most traditional buffer overflow exploits work by overriding the return
|
||||||
|
address in the current stack frame, preventing or at least detecting this, can
|
||||||
|
be quite effective without much overhead at runtime. Chiueh et al describe a
|
||||||
|
technique that stores a redudnant copy of the return address in a secure memory
|
||||||
|
area that is guarded by read-only memory, so it cannot be overwritten by
|
||||||
|
overflows. When returning, the copy of the return address is compared to the one
|
||||||
|
in the current stack frame and only, if it matches, the ret instruction is
|
||||||
|
actually executed\cite{Rad2001}. While this is effective against return oriented
|
||||||
|
programming based exploits, it does not protect against vtable overrides.
|
||||||
|
|
||||||
|
An older technique from 1998 proposes to put a canary word between the data of a
|
||||||
|
stack frame and the return address\cite{Stackguard1998}. When returning, the
|
||||||
|
canary is checked, if it is still intact and if not, a buffer overflow occurred.
|
||||||
|
This technique is used in major operating systems %TODO
|
||||||
|
but can be defeted, if there is an information leak that leaks the cannary to
|
||||||
|
the attacker. The attacker is then able to construct a payload, that keeps the
|
||||||
|
canary intact.
|
||||||
|
|
||||||
\subsubsection{Restricting Language Features to a Secure Subset}
|
\subsubsection{Restricting Language Features to a Secure Subset}
|
||||||
\subsubsection{Static Analysis}
|
\subsubsection{Static Analysis}
|
||||||
\subsubsection{Type System Solutions}
|
\subsubsection{Type System Solutions}
|
||||||
|
|
||||||
|
Condit et al propose an extension to the C type system that extends it with
|
||||||
|
dependent types. These types have an associated value, e.g. a pointer type can
|
||||||
|
have the buffer size associated to it. This prevents indexing into a buffer with
|
||||||
|
out of bounds values.
|
||||||
|
|
||||||
\subsubsection{ASLR}
|
\subsubsection{ASLR}
|
||||||
|
|
||||||
ASLR aims to prevent exploitatoin of buffer overflows by placing code at random
|
ASLR aims to prevent exploitatoin of buffer overflows by placing code at random
|
||||||
@ -127,7 +159,16 @@ text
|
|||||||
|
|
||||||
\section{Conclusion and Outlook}\label{ref:conclusion}
|
\section{Conclusion and Outlook}\label{ref:conclusion}
|
||||||
|
|
||||||
text
|
While there are many techniques, that protect against different types of buffer
|
||||||
|
overflows, none of them is effctive in every situation. Maybe we've come to a
|
||||||
|
point where we have to stop using memory unsafe languages where it is not
|
||||||
|
inevitable. There are many modern programming languages, that aim for the same
|
||||||
|
problem space as C, C++ or Fortran but without the issues comming/stemming %TODO
|
||||||
|
from these languages. If it is feasible to use a garbage collector, Go might
|
||||||
|
work just fine. If real-time properties are required, Rust could be the way to
|
||||||
|
go, without any language runtime and with deterministic memory management. For
|
||||||
|
any other problem, almost any other memory safe language is better than using
|
||||||
|
unsafe C.
|
||||||
|
|
||||||
\section{Sources}
|
\section{Sources}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user