Changes
This commit is contained in:
parent
97a17b572e
commit
44e15ac978
BIN
work/01paper.pdf
BIN
work/01paper.pdf
Binary file not shown.
245
work/01paper.tex
245
work/01paper.tex
@ -65,7 +65,14 @@ MatrNr. 3220018}
|
|||||||
This paper tries to explain the details behind buffer overflows, explore the
|
This paper tries to explain the details behind buffer overflows, explore the
|
||||||
problems stemming from those kinds of software vulnerabilities and discus
|
problems stemming from those kinds of software vulnerabilities and discus
|
||||||
possible countermeasures with focus on their effectiveness, performance impact
|
possible countermeasures with focus on their effectiveness, performance impact
|
||||||
and ease of use.
|
and ease of use. It discusses compiler based (such as ASLR, NX, stack
|
||||||
|
canaries) as well as type system based (e.g.\ dependent types) solutions to
|
||||||
|
this prevalent type of software bugs based on their performance impact and the
|
||||||
|
effort needed to introduce the mitigations into existing software projects. An
|
||||||
|
analysis of the current state of the art informs the reader about what to
|
||||||
|
expect when writing software today. The analysis shows that most techniques
|
||||||
|
actually tackle the problem of exploiting buffer overflows for code execution
|
||||||
|
but do nothing to prevent introducing them in the first place.
|
||||||
|
|
||||||
\end{abstract}
|
\end{abstract}
|
||||||
|
|
||||||
@ -77,27 +84,26 @@ Buffer Overflow, Software Security
|
|||||||
|
|
||||||
\section{Motivation}\label{ref:motivation}
|
\section{Motivation}\label{ref:motivation}
|
||||||
|
|
||||||
When the first programming languages were designed, memory had to be managed
|
In the early days of programming, memory as managed manually to make the best
|
||||||
manually to make the best use of slow hardware. This opened the door for many
|
use of slow hardware and low memory. This opened the door for many kinds of
|
||||||
kinds of programming errors. Memory can be deallocated more than once
|
programming errors. Memory can be deallocated more than once (double-free),
|
||||||
(double-free), invalid pointers can be dereferenced (\mintinline{C}{NULL}
|
invalid pointers can be dereferenced (\mintinline{C}{NULL} pointer dereference;
|
||||||
pointer dereference; this is still a problem in many modern languages) or the
|
this is still a problem in many modern languages) or the program could read or
|
||||||
program could read or write out of bounds of a buffer (information leaks,
|
write out of bounds of a buffer (information leaks, \acp{bof}). Languages that
|
||||||
\acp{bof}). Languages that are affected by this are e.g.\ C, C++ and Fortran.
|
are affected by this are e.g.\ C, C++ and Fortran. While modern programming
|
||||||
While most if not all of these problems are solved in modern programming
|
languages solve most if not all of these problems, critical parts of the worlds
|
||||||
languages, these languages are still used in critical parts of the worlds
|
infrastructure are still implemented in these old languages, either because they
|
||||||
infrastructure, either because they allow to implement really performant
|
allow the implementation of really performant programs, offer deterministic
|
||||||
programs, offer deterministic runtime behaviour (e.g.\ no pauses due to garbage
|
runtime behaviour (e.g.\ no pauses due to garbage collection), because they
|
||||||
collection), because they power legacy systems or for portability reasons.
|
power legacy systems or for portability reasons. Scientists and software
|
||||||
Scientists and software engineers have proposed lots of solutions to this
|
engineers have proposed lots of solutions to this problem over the years and
|
||||||
problem over the years and this paper aims to compare and give an overview about
|
this paper aims to compare and give an overview about those.
|
||||||
those.
|
|
||||||
|
|
||||||
Reading out of bounds can result in an information leak and is less critical
|
Reading out of bounds can result in an information leak and is one of the less
|
||||||
than \acp{bof} in most cases, but there are exceptions, e.g.\ the Heartbleed
|
critical results of \ac{bof} in most cases, but there are exceptions, e.g.\ the
|
||||||
bug~\cite{Heardbleed2014} in OpenSSL which allowed dumping secret keys from
|
Heartbleed bug~\cite{Heardbleed2014} in OpenSSL which allowed dumping secret
|
||||||
memory. Out of bounds writes are almost always critical and result in code
|
keys from memory. Out of bounds writes are almost always critical and result in
|
||||||
execution vulnerabilities or at least application crashes.
|
code execution vulnerabilities or at least application crashes.
|
||||||
|
|
||||||
In 2018, 14\% (2368 out of 16556)~\cite{Cve2018} of all software vulnerabilities
|
In 2018, 14\% (2368 out of 16556)~\cite{Cve2018} of all software vulnerabilities
|
||||||
that have a CVE assigned, were overflow related. This shows that, even if this
|
that have a CVE assigned, were overflow related. This shows that, even if this
|
||||||
@ -115,8 +121,7 @@ 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
|
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
|
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
|
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
|
C++) overwriting the \ac{vmt}, which stores the pointers to an object's methods.
|
||||||
stored.
|
|
||||||
|
|
||||||
A simple vulnerable C program might look like this:
|
A simple vulnerable C program might look like this:
|
||||||
|
|
||||||
@ -139,18 +144,18 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
A successful stack \ac{bof} exploit would place the payload in the memory by
|
A successful stack \ac{bof} exploit would place the payload in the memory by
|
||||||
supplying it as an argument to the program (or by placing it in an environment
|
supplying it as an argument to the program (or by placing it in an environment
|
||||||
variable, writing it to a file that the program reads, via network packet, ...)
|
variable, writing it to a file that the program reads, via network packet,
|
||||||
and eventually overwrite the return address by providing an input with $> 50$
|
\dots) and eventually overwrite the return address by providing an input with
|
||||||
bytes and therefore writing out of bounds. When executing the
|
more than 50 bytes and therefore writing out of bounds. When executing the
|
||||||
\mintinline{C}{return} instruction, and the jumps into the payload, the
|
\mintinline{C}{return} instruction, and the \ac{ip} jumps into the payload, the
|
||||||
attacker's code is executed. This works due to the way, how function calls on
|
attacker's code is executed. This works due to the way, how CPUs perform
|
||||||
CPUs work: The stack frame of the current function lies between the \ac{bp} and
|
function calls: The stack frame of the current function lies between the \ac{bp}
|
||||||
\ac{sp} as shown in~\cref{fig:before}. When a function is called, the value
|
and \ac{sp} as shown in~\cref{fig:before}. When calling a function, the value of
|
||||||
of the \ac{bp} and \ac{ip} is pushed to the stack (\cref{fig:call}) and the
|
the \ac{bp} and \ac{ip} is pushed to the stack (\cref{fig:call}) and the CPU
|
||||||
\ac{ip} is set to the address of the called function. When the function returns,
|
writes the address of the called function into the \ac{ip}. When the function
|
||||||
the old \ac{ip} is restored from the stack and the execution continues from
|
returns, after restoring the old \ac{ip} from the stack, the execution continues
|
||||||
where the function was called. If an overflow overwrites the old \ac{ip}
|
from where the function call occurred earlier. If an overflow overwrites the old
|
||||||
(\cref{fig:exploit}), the attacker controls where execution continues.
|
\ac{ip} (\cref{fig:exploit}), the attacker controls where execution continues.
|
||||||
|
|
||||||
\begin{figure}[h!]
|
\begin{figure}[h!]
|
||||||
\begin{subfigure}[b]{.3\textwidth}
|
\begin{subfigure}[b]{.3\textwidth}
|
||||||
@ -177,23 +182,23 @@ This is only one of several types and exploitation techniques. Others include
|
|||||||
\item Heap-based \ac{bof}: In this case there is no way of overwriting the
|
\item Heap-based \ac{bof}: In this case there is no way of overwriting the
|
||||||
return address but objects on the heap might contain function pointers
|
return address but objects on the heap might contain function pointers
|
||||||
(e.g.\ for dynamic dispatch) which can be overwritten to execute the
|
(e.g.\ for dynamic dispatch) which can be overwritten to execute the
|
||||||
attackers code, when executed~\cite{Detection2018}.
|
attackers code, when called~\cite{Detection2018}.
|
||||||
|
|
||||||
\item Integer overflow: Some calculation on fixed sized integers is used to
|
\item Integer overflow: Some calculation on fixed sized integers is used to
|
||||||
allocate memory. The calculation leads to an integer overflow and only a
|
allocate memory. The calculation leads to an integer overflow and only a
|
||||||
small buffer is allocated~\cite{Detection2018}. Later a big integer into the
|
small buffer is allocated~\cite{Detection2018}. Later the buffer is indexed
|
||||||
buffer is used and reads or writes outside the buffer. This kind of
|
with a big integer and performs a read or write outside the buffer. This
|
||||||
vulnerability can also lead to other problems because at least in C, signed
|
kind of vulnerability can also lead to other problems because at least in C,
|
||||||
integer overflow is undefined behaviour.
|
signed integer overflow is undefined behaviour.
|
||||||
|
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
This paper won't explore other kinds of \ac{bof} in detail because the concept
|
This paper does not explore other kinds of \ac{bof} in detail because the
|
||||||
is always the same: Unchecked indexing into memory allows the attacker to
|
concept is always the same: Unchecked indexing into memory allows the attacker
|
||||||
overwrite some kind of return or call address, which allows hijacking of the
|
to overwrite some kind of return or call address, which allows hijacking of the
|
||||||
execution flow.
|
execution flow.
|
||||||
|
|
||||||
The most trivial kinds of payloads is known as a \mintinline{ASM}{NOP} sled.
|
The most trivial kind of payloads is known as a \mintinline{ASM}{NOP} sled.
|
||||||
Here the attacker appends as many \mintinline{ASM}{NOP} instructions before any
|
Here the attacker appends as many \mintinline{ASM}{NOP} instructions before any
|
||||||
shell-code (e.g.\ to invoke \mintinline{shell}{/bin/sh}) and points the
|
shell-code (e.g.\ to invoke \mintinline{shell}{/bin/sh}) and points the
|
||||||
overwritten \ac{ip} or function pointer somewhere inside the
|
overwritten \ac{ip} or function pointer somewhere inside the
|
||||||
@ -218,7 +223,7 @@ problems introduced by \acp{bof} and tries to answer the following questions:
|
|||||||
\acp{bof}?
|
\acp{bof}?
|
||||||
|
|
||||||
\item How realistic is it for developers to use the technique in real-world
|
\item How realistic is it for developers to use the technique in real-world
|
||||||
code? Can it be introduced incrementally?
|
code? Is an incremental introduction possible?
|
||||||
|
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
@ -228,12 +233,12 @@ techniques are language agnostic but this is not a focus of this paper. In the
|
|||||||
end, there is a discussion about the current state.
|
end, there is a discussion about the current state.
|
||||||
|
|
||||||
For the literature research, the paper~\citetitle{Detection2018} served as a
|
For the literature research, the paper~\citetitle{Detection2018} served as a
|
||||||
base. From there a snowball system search with combinations of the keywords
|
base. From there on, the author performed a snowball system search with
|
||||||
\enquote{buffer}, \enquote{overflow}, \enquote{detection}, \enquote{prevention}
|
combinations of the keywords \enquote{buffer}, \enquote{overflow},
|
||||||
and \enquote{dependent typing} was performed using
|
\enquote{detection}, \enquote{prevention} and \enquote{dependent typing} using
|
||||||
\url{https://scholar.google.com/}.
|
\url{https://scholar.google.com/}.
|
||||||
|
|
||||||
Results are evaluated and prioritized using the following criteria:
|
Evaluation and prioritization of results is done using the following criteria:
|
||||||
|
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
|
|
||||||
@ -264,49 +269,50 @@ The easiest and maybe single most effective method to prevent \acp{bof} is to
|
|||||||
check, if a write or read operation is out of bounds. This requires storing the
|
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 (so called fat
|
size of a buffer together with the pointer to the buffer (so called fat
|
||||||
pointers) and check for each read or write in the buffer, if it is in bounds at
|
pointers) and check for each read or write in the buffer, if it is in bounds at
|
||||||
runtime. Still almost any language that comes with a runtime, uses runtime
|
runtime. Almost any language that comes with a managed runtime, uses \ac{rbc}.
|
||||||
checking. For this technique to be effective effective in general, writes to a
|
For this technique to be effective effective in general, writes to raw pointers
|
||||||
raw pointer must be disallowed. Otherwise the security checks can be
|
must be disallowed. Otherwise the security checks can be circumvented. \Ac{rbc}
|
||||||
circumvented. \Ac{rbc} introduces a runtime overhead for every indexed read or
|
introduces a runtime overhead for every indexed read or write operation. This is
|
||||||
write operation. This is a problem if a program runs on limited hardware or
|
a problem if a program runs on limited hardware or might impact real-time
|
||||||
might impact real-time properties.
|
properties.
|
||||||
|
|
||||||
Introducing \ac{rbc} into an existing codebase is not easy. Using fat pointers
|
Introducing \ac{rbc} into an existing codebase is not easy. Using fat pointers
|
||||||
in a few functions does not prevent other parts of the code to use raw pointers
|
in a few functions does not prevent other parts of the code to use raw pointers
|
||||||
into the same buffer. So for this to be effective, the whole codebase needs to
|
into the same buffer. So for this to be effective, the whole codebase needs to
|
||||||
be changed to disallow raw pointers, which, depending on the size, might not be
|
be changed to disallow raw pointers, which, depending on the size, might not be
|
||||||
feasible. Still, if done correctly and consequently, it is simply impossible to
|
feasible. Still, if done correctly and consequently, there will be no \ac{bof}
|
||||||
exploit \acp{bof} for code execution. \Ac{dos} is still possible because the
|
vulnerabilities. \Ac{dos} might is still possible depending on how invalid
|
||||||
program terminates gracefully when a out of bounds index is used.
|
indexing is handled, because the program might terminate gracefully when a out
|
||||||
|
of bounds index is used.
|
||||||
|
|
||||||
\subsection{Prevent/Detect Overwriting Return Address}
|
\subsection{Prevent/Detect Overwriting Return Address}
|
||||||
|
|
||||||
Since most traditional \ac{bof} exploits work by overwriting the return address
|
Since stack based \ac{bof} exploits work by overwriting the return address in
|
||||||
in the current stack frame, preventing or at least detecting this, can be quite
|
the current stack frame, preventing or at least detecting this, can be quite
|
||||||
effective without much overhead at runtime. \citeauthor{Rad2001} describe a
|
effective without much overhead at runtime. \citeauthor{Rad2001} describe a
|
||||||
technique that stores a redundant copy of the return address in a secure memory
|
technique that stores a redundant copy of the return address in a secure memory
|
||||||
area that is guarded by read-only memory, so it cannot be overwritten by
|
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
|
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 \mintinline{ASM}{RET}
|
in the current stack frame and only if it matches, the \mintinline{ASM}{RET}
|
||||||
instruction is actually executed~\cite{Rad2001}. While this is effective against
|
instruction is actually executed~\cite{Rad2001}. While this is effective against
|
||||||
stack based \acp{bof}, in the described form, it does not protect against vtable
|
stack based \acp{bof}, in the described form, it does not protect against
|
||||||
overwrites. An extension could be made to also protect the \ac{plt} and vtables
|
\ac{vmt} or \ac{plt} overwrites. An extension could be made to also protect the
|
||||||
but custom constructs using function pointers would still be vulnerable. Since
|
\ac{plt} and \ac{vmt} but custom constructs using function pointers would remain
|
||||||
this technique is a compiler extension, no modification of the codebase is
|
vulnerable. Since this technique is a compiler extension, no modification of the
|
||||||
required to enable it, and while it does not prevent all kinds of \ac{bof},
|
codebase is required to enable it, and while it does not prevent all kinds of
|
||||||
mitigates all stack based \acp{bof} with only minimal overhead when calling and
|
\ac{bof}, it mitigates all stack based \acp{bof} with only minimal overhead when
|
||||||
returning from a function.
|
calling and returning from a function.
|
||||||
|
|
||||||
An older technique from 1998 proposes to put a canary word (named after the
|
An older technique from 1998 proposes to put a canary word (named after the
|
||||||
canaries that were used in mines to detect low oxygen levels) between the data
|
canaries that were used in mines to detect low oxygen levels) between the data
|
||||||
of a stack frame and the return address~\cite{Stackguard1998}\cite{AtkDef2016}.
|
of a stack frame and the return address~\cite{Stackguard1998}\cite{AtkDef2016}.
|
||||||
When returning, the canary is checked, if it is still intact and if not, a
|
When returning, a check is performed, to confirm, the canary is intact, if it is
|
||||||
\ac{bof} occurred. This technique is implemented by major
|
not, a \ac{bof} occurred. This technique is implemented by major
|
||||||
compilers~\cite{Gcc2003} but can be defeated, if there is an information leak
|
compilers~\cite{Gcc2003} but can be defeated, if there is an information leak
|
||||||
that leaks the canary to the attacker. The attacker is then able to construct a
|
that leaks the canary to the attacker. The attacker is then able to construct a
|
||||||
payload, that keeps the canary intact. This mitigation has a minimal
|
payload, that keeps the canary intact. This mitigation has a minimal performance
|
||||||
performance impact~\cite{Gcc2003} and offers a good level of protection. It is a
|
impact~\cite{Gcc2003} and offers a good level of protection. It is a compiler
|
||||||
compiler extension so no modification of the code base is needed.
|
extension so there is no need for modification of the code base.
|
||||||
|
|
||||||
\subsection{Type System Solutions}
|
\subsection{Type System Solutions}
|
||||||
|
|
||||||
@ -314,15 +320,16 @@ compiler extension so no modification of the code base is needed.
|
|||||||
with dependent types. These types have an associated value, e.g.\ a pointer type
|
with dependent types. These types have an associated value, e.g.\ a pointer type
|
||||||
can have the buffer size associated to it~\cite{Dep2007}. This prevents indexing
|
can have the buffer size associated to it~\cite{Dep2007}. This prevents indexing
|
||||||
into a buffer with out-of-bounds values. This extension is a superset of C so
|
into a buffer with out-of-bounds values. This extension is a superset of C so
|
||||||
any valid C code can be compiled using the extension and the codebase is
|
compilation of any valid C code is possible using the extension and incremental
|
||||||
improved incrementally. If the type extension is advanced enough, the
|
improvement of the codebase is possible. If the type extension is advanced
|
||||||
additional information might form the base for a formal verification. In some
|
enough, the additional information might form the base for a formal
|
||||||
cases, the type extensions can even be inferred~\cite{Dep2007}.
|
verification. In some cases, inference of the type extensions is
|
||||||
|
possible~\cite{Dep2007}.
|
||||||
|
|
||||||
This technique prevents all kinds of overflows, if used, but requires changes to
|
This technique prevents all kinds of overflows, if used, but requires changes to
|
||||||
the codebase and is only effective where these changes are applied. Since it is
|
the codebase and is only effective where these changes are applied. Since it is
|
||||||
a compile-time solution, it does affect the compile-time but has no negative
|
a compile-time solution, it affects the compile-time but has no negative effect
|
||||||
effect on the runtime.
|
on the runtime.
|
||||||
|
|
||||||
\subsection{Address Space Layout Randomization}
|
\subsection{Address Space Layout Randomization}
|
||||||
|
|
||||||
@ -343,20 +350,20 @@ program.
|
|||||||
|
|
||||||
w\^{}x (also known as \ac{nx} or \ac{dep}) makes memory either writable or
|
w\^{}x (also known as \ac{nx} or \ac{dep}) makes memory either writable or
|
||||||
executable~\cite{AtkDef2016}. That way, an attacker cannot place arbitrary
|
executable~\cite{AtkDef2016}. That way, an attacker cannot place arbitrary
|
||||||
payloads in memory. There are still techniques to exploit this by reusing
|
payloads in memory. There are still techniques to exploit this by reusing
|
||||||
existing executable code. The ret-to-libc exploiting technique uses existing
|
existing executable code. The ret-to-libc exploiting technique uses existing
|
||||||
calls to the libc with attacker controlled parameters, e.g.\ if the program uses
|
calls to the libc with attacker controlled parameters, e.g.\ if the program uses
|
||||||
the \mintinline{shell}{system} command, the attacker can plant
|
the \mintinline{shell}{system} command, the attacker can plant
|
||||||
\mintinline{shell}{/bin/sh} as parameter on the stack, followed by the address
|
\mintinline{shell}{/bin/sh} as parameter on the stack, followed by the address
|
||||||
of \mintinline{shell}{system} and get a shell on the system. \ac{rop} (a
|
of \mintinline{shell}{system} and get a shell on the system. \Ac{rop} (a
|
||||||
superset of ret-to-libc exploits) uses so called \ac{rop} gadgets, combinations
|
superset of ret-to-libc exploits) uses so called \ac{rop} gadgets, combinations
|
||||||
of memory modifying instructions followed by the \mintinline{ASM}{RET}
|
of memory modifying instructions followed by the \mintinline{ASM}{RET}
|
||||||
instruction to build instruction chains, that execute the desired shell-code.
|
instruction to build instruction chains, that execute the desired shell-code.
|
||||||
This is done by placing the desired return addresses in the right order on the
|
This is achieved by placing the desired return addresses in the right order on
|
||||||
stack and reuses the existing code to circumvent the w\^{}x protection. These
|
the stack and reuses the existing code to circumvent the w\^{}x protection.
|
||||||
combinations of memory modification followed by \mintinline{ASM}{RET}
|
These combinations of memory modification followed by \mintinline{ASM}{RET}
|
||||||
instructions are called \ac{rop} chains and are Turing complete~\cite{Rop2007},
|
instructions, known as \ac{rop} chains, are Turing complete~\cite{Rop2007}, so
|
||||||
so in theory it is possible to implement any imaginable payload, as long as the
|
in theory it is possible to construct any imaginable payload, as long as the
|
||||||
exploited program contains enough gadgets and the overflowing buffer has enough
|
exploited program contains enough gadgets and the overflowing buffer has enough
|
||||||
space.
|
space.
|
||||||
|
|
||||||
@ -367,22 +374,23 @@ space.
|
|||||||
|
|
||||||
\subsubsection{\ac{aslr}}
|
\subsubsection{\ac{aslr}}
|
||||||
|
|
||||||
\Ac{aslr} has been proven effective and is wildly used in production. It is
|
\Ac{aslr} has proven effective and sees wide use in production. Most major
|
||||||
included in most major operating systems~\cite{FBSDaslr}. Some even use kernel
|
operating systems implement this technique~\cite{FBSDaslr}. Some even use kernel
|
||||||
\ac{aslr}~\cite{Linuxaslr}. Since this mechanism is active at runtime, it does
|
\ac{aslr}~\cite{Linuxaslr}. Since this mechanism is active at runtime, it does
|
||||||
not require any changes in the code itself, the program only has to be compiled
|
not require any changes in the code itself, the program only has to be compiled
|
||||||
as a \ac{pie}. On 32-bit CPUs, only 16-bit of the address are randomized. These
|
as a \ac{pie}. On 32-bit CPUs, only 16-bit of the address are randomized. These
|
||||||
16-bit can be brute forced in a few minutes or seconds~\cite{AslrEffective2004}.
|
16-bit can be brute forced in a few minutes or seconds~\cite{AslrEffective2004}.
|
||||||
|
|
||||||
There is no runtime overhead since the only change is the position of the
|
There is no runtime overhead since the only change is the position of the
|
||||||
program in memory. Since there is no additional work except maybe recompilation,
|
program in memory. Since there is no additional work required except maybe
|
||||||
this technique can and should be used on modern systems.
|
recompilation, this technique can and should be used on modern systems.
|
||||||
|
|
||||||
\subsubsection{w\^{}x}
|
\subsubsection{w\^{}x}
|
||||||
|
|
||||||
With the rise of \ac{rop} techniques, w\^{}x protection has been shown to be
|
The rise of code reuse exploits like \ac{rop} and ret-to-libc, shows the
|
||||||
ineffective. It makes vulnerabilities harder to exploit by preventing the most
|
ineffectiveness of w\^{}x protection. It makes vulnerabilities harder to exploit
|
||||||
naive types of payloads but it doesn't actually prevent exploits from happening.
|
by preventing the most naive types of payloads but it doesn't actually prevent
|
||||||
|
exploits from happening.
|
||||||
|
|
||||||
\Ac{nx} does not prevent any exploits but makes it harder for an attacker that
|
\Ac{nx} does not prevent any exploits but makes it harder for an attacker that
|
||||||
does not know the system, the program is running on (e.g.\ a network service).
|
does not know the system, the program is running on (e.g.\ a network service).
|
||||||
@ -398,7 +406,7 @@ might introduce other problems.
|
|||||||
|
|
||||||
\subsection{State of the Art}
|
\subsection{State of the Art}
|
||||||
|
|
||||||
Operating systems started to compile C code to \ac{pie} by
|
Operating systems started to compile C code to \acp{pie} by
|
||||||
default~\cite{ArchPie2017} and \ac{aslr} is enabled, too. Same goes for \ac{nx}
|
default~\cite{ArchPie2017} and \ac{aslr} is enabled, too. Same goes for \ac{nx}
|
||||||
and stack canaries~\cite{ArchPie2017}. The combination of these mitigations
|
and stack canaries~\cite{ArchPie2017}. The combination of these mitigations
|
||||||
makes it hard to write general exploits for modern operating systems.
|
makes it hard to write general exploits for modern operating systems.
|
||||||
@ -406,7 +414,7 @@ makes it hard to write general exploits for modern operating systems.
|
|||||||
To check the current state, the author investigates, which mitigations are
|
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
|
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
|
commit of the LLVM-project (\mintinline[breaklines]{shell}{181ab91efc9}) by
|
||||||
compiling both compilers using the default configuration. The experiments are
|
building 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
|
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:
|
kernel. The following commands compile the source codes:
|
||||||
|
|
||||||
@ -441,12 +449,13 @@ kernel. The following commands compile the source codes:
|
|||||||
The \mintinline{shell}{build}, \mintinline{shell}{host} and
|
The \mintinline{shell}{build}, \mintinline{shell}{host} and
|
||||||
\mintinline{shell}{target} parameters in~\cref{lst:gcc} describe the target
|
\mintinline{shell}{target} parameters in~\cref{lst:gcc} describe the target
|
||||||
platform for the compiler and \mintinline{shell}{disable-multilib} disables
|
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
|
32-bit support, which is not needed for this experiment. The
|
||||||
available cores for compilation. \mintinline{shell}{CMAKE_BUILD_TYPE=Release}
|
\mintinline{sh}{-j8} flag only tells make to use all 8 available cores for
|
||||||
creates a release build of the clang compiler (see~\cref{lst:clang}).
|
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
|
The fresh builds of \ac{gcc} and clang compile the code from~\cref{lst:vuln} to
|
||||||
check which mitigations are enabled by default. Using
|
check which mitigations are enabled by default. After using
|
||||||
\mintinline[breaklines]{shell}{gcc -o vuln.gcc vuln.c} and
|
\mintinline[breaklines]{shell}{gcc -o vuln.gcc vuln.c} and
|
||||||
\mintinline[breaklines]{shell}{clang -o vuln.clang vuln.c} to compile the source
|
\mintinline[breaklines]{shell}{clang -o vuln.clang vuln.c} to compile the source
|
||||||
code, the \mintinline{shell}{checksec.sh} tool~\cite{Checksec2019} shows which
|
code, the \mintinline{shell}{checksec.sh} tool~\cite{Checksec2019} shows which
|
||||||
@ -506,40 +515,6 @@ properties are required, Rust could be the way to go, without any language
|
|||||||
runtime and with deterministic memory management. For any other problem, almost
|
runtime and with deterministic memory management. For any other problem, almost
|
||||||
any other memory safe language is better than using unsafe C.
|
any other memory safe language is better than using unsafe C.
|
||||||
|
|
||||||
% \section{Sources (Dummy Section for Deadline)}
|
|
||||||
|
|
||||||
% \begin{itemize}
|
|
||||||
|
|
||||||
% \item RAD:\ A Compile-Time Solution to Buffer Overflow Attacks~\cite{Rad2001}
|
|
||||||
% (might not protect against e.g.\ vtable overwrites, \ac{plt} address
|
|
||||||
% changes, \dots)
|
|
||||||
|
|
||||||
% \item Dependent types for low-level programming~\cite{Dep2007}
|
|
||||||
|
|
||||||
% \item StackGuard: Automatic Adaptive Detection and Prevention of
|
|
||||||
% Buffer-Overflow Attachs~\cite{Stackguard1998} (ineffective in combination
|
|
||||||
% with information leaks)
|
|
||||||
|
|
||||||
% \item Type-Assisted Dynamic Buffer Overflow Detection~\cite{TypeAssisted2002}
|
|
||||||
|
|
||||||
% \item On the Effectiveness of NX, SSP, RenewSSP, and \ac{aslr} against Stack
|
|
||||||
% Buffer Overflows~\cite{Effectiveness2014}
|
|
||||||
|
|
||||||
% \item What Do We Know About Buffer Overflow Detection?: A Survey on Techniques
|
|
||||||
% to Detect A Persistent Vulnerability~\cite{Detection2018}
|
|
||||||
|
|
||||||
% \item Survey of Attacks and Defenses on Stack-based Buffer Overflow
|
|
||||||
% Vulnerability~\cite{AtkDef2016}
|
|
||||||
|
|
||||||
% \item Beyond stack smashing: recent advances in exploiting buffer
|
|
||||||
% overruns~\cite{Smashing2004}
|
|
||||||
|
|
||||||
% \item Runtime countermeasures for code injection attacks against C and C++
|
|
||||||
% programs~\cite{Counter2012}
|
|
||||||
|
|
||||||
% \end{itemize}
|
|
||||||
|
|
||||||
|
|
||||||
\printbibliography{}
|
\printbibliography{}
|
||||||
% \bibliographystyle{IEEEtran}
|
% \bibliographystyle{IEEEtran}
|
||||||
% \bibliography{bibliography}
|
% \bibliography{bibliography}
|
||||||
|
@ -62,3 +62,8 @@
|
|||||||
short = DEP,
|
short = DEP,
|
||||||
long = data execution prevention
|
long = data execution prevention
|
||||||
}
|
}
|
||||||
|
|
||||||
|
\DeclareAcronym{vmt}{
|
||||||
|
short = VMT,
|
||||||
|
long = virtual method table
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user