This commit is contained in:
Valentin Brandl 2019-12-17 11:04:27 +01:00
parent 44c97f0831
commit 97a17b572e
No known key found for this signature in database
GPG Key ID: 30D341DD34118D7D
2 changed files with 29 additions and 29 deletions

Binary file not shown.

View File

@ -81,7 +81,7 @@ When the first programming languages were designed, memory had to be managed
manually to make the best use of slow hardware. This opened the door for many
kinds of programming errors. Memory can be deallocated more than once
(double-free), invalid pointers can be dereferenced (\mintinline{C}{NULL}
pointer dereference; this is still a problem in many modern languages), the
pointer dereference; this is still a problem in many modern languages) or the
program could read or write out of bounds of a buffer (information leaks,
\acp{bof}). Languages that are affected by this are e.g.\ C, C++ and Fortran.
While most if not all of these problems are solved in modern programming
@ -110,13 +110,13 @@ type of bug is very old and well known, it's still relevant today.
Code execution via \ac{bof} vulnerabilities almost always works by overwriting
the return address in the current stack frame (known as \enquote{stack
smashing})~\cite{Smashing2004}, so when the \mintinline{ASM}{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~\cite{Detection2018}. Other ways include overwriting addresses in the
\ac{plt} (the \ac{plt} contains addresses of dynamically linked library
functions) of a binary so that, if a linked function is called, an attacker
controlled function is called instead, or (in C++) overwriting the vtable where
the pointers to an object's methods are stored.
executed, an attacker controlled address is moved into the \ac{ip} register and
the code pointed to by this address is executed~\cite{Detection2018}. Other ways
include overwriting addresses in the \ac{plt} (the \ac{plt} contains addresses
of dynamically linked library functions) of a binary so that, if a linked
function is called, an attacker controlled function is called instead, or (in
C++) overwriting the vtable where the pointers to an object's methods are
stored.
A simple vulnerable C program might look like this:
@ -308,8 +308,6 @@ payload, that keeps the canary intact. This mitigation has a minimal
performance impact~\cite{Gcc2003} and offers a good level of protection. It is a
compiler extension so no modification of the code base is needed.
% \subsection{Restricting Language Features to a Secure Subset}
% \subsection{Static Analysis}
\subsection{Type System Solutions}
\citeauthor{Dep2007} propose an extension to the C type system that extends it
@ -405,11 +403,12 @@ default~\cite{ArchPie2017} and \ac{aslr} is enabled, too. Same goes for \ac{nx}
and stack canaries~\cite{ArchPie2017}. The combination of these mitigations
makes it hard to write general exploits for modern operating systems.
To check the current state, the latest release of the \ac{gcc} (9.2) and the
latest commit of the LLVM-project (\mintinline[breaklines]{shell}{181ab91efc9})
are compiled using the default configuration. The experiments are performed on a
64-bit Debian 9.11 system running on version 4.19.0 of the Linux kernel. The
following commands are used for compilation:
To check the current state, the author investigates, which mitigations are
enabled by default in the latest release (9.2) of the \ac{gcc} and the latest
commit of the LLVM-project (\mintinline[breaklines]{shell}{181ab91efc9}) by
compiling both compilers using the default configuration. The experiments are
performed on a 64-bit Debian 9.11 system running on version 4.19.0 of the Linux
kernel. The following commands compile the source codes:
\begin{figure}[h!]
\begin{subfigure}[b]{.3\textwidth}
@ -435,15 +434,16 @@ following commands are used for compilation:
-G "Unix Makefiles" ../llvm \
&& make -j8
\end{minted}
\caption{clang compilation script}
\caption{clang compilation script}\label{lst:clang}
\end{subfigure}
\end{figure}
The \mintinline{shell}{build}, \mintinline{shell}{host} and
\mintinline{shell}{target} parameters in~\ref{lst:gcc} only describe the target
\mintinline{shell}{target} parameters in~\cref{lst:gcc} describe the target
platform for the compiler and \mintinline{shell}{disable-multilib} disables
32-bit support. The \mintinline{sh}{-j8} flag only tells make to use all 8
available cores for compilation.
available cores for compilation. \mintinline{shell}{CMAKE_BUILD_TYPE=Release}
creates a release build of the clang compiler (see~\cref{lst:clang}).
The fresh builds of \ac{gcc} and clang compile the code from~\cref{lst:vuln} to
check which mitigations are enabled by default. Using
@ -454,7 +454,7 @@ mitigations are active in the new binary:
\begin{table}[h!]
\begin{center}
\begin{tabular}{lll}
\begin{tabular}{lrr}
\toprule
Mitigation & Active in \ac{gcc}? & Active in clang? \\
\toprule
@ -471,16 +471,16 @@ mitigations are active in the new binary:
\end{table}
Surprisingly enough, two of the most popular C compilers enable only one of the
described compile-time mitigations by default. Maintainer of operating system
packages of the compiler might choose a more secure configuration for the
compiler as shown in~\cite{ArchPie2017} but still, compiler vendors might want
to choose better defaults, too.
described compile-time mitigations by default (see~\cref{tab:mitigations}).
Maintainer of operating system packages of the compiler might choose a more
secure configuration for the compiler as shown in~\cite{ArchPie2017} but still,
compiler vendors might want to choose better defaults, too.
So far, all described mitigations don't change anything about the existence of
So far, all discussed mitigations don't change anything about the existence of
\acp{bof} but just try to prevent the exploitation for code execution. The
vulnerable programs will still terminate if the stack canary is overwritten, a
call into \ac{nx} memory occurs or execution continues inside garbage data due
to \ac{aslr}. The underlying problem persists, only the worst results are
vulnerable programs terminate if the stack canary is overwritten, a call into
\ac{nx} memory occurs or execution continues inside garbage data due to
\ac{aslr}. The underlying problem persists, only the worst results are
mitigated. \Ac{dos} is still a problem in safety critical systems (e.g.\ cars,
planes, medical devices) or in any area with real-time requirements.
@ -496,8 +496,8 @@ critical software.
While there are many techniques, that protect against different types of
\acp{bof}, none of them is effective in every situation but in combination they
offer good protection against code execution attacks. Maybe we've come to a
point where we have to stop using memory unsafe languages where it is not
offer good protection against code execution attacks. Maybe the time has come,
where usage of memory unsafe languages has to be stopped 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 coming from these
languages. If it is feasible to use a garbage collector, languages like Go, Java