This commit is contained in:
Valentin Brandl 2019-12-17 21:27:03 +01:00
parent 97a17b572e
commit 44e15ac978
No known key found for this signature in database
GPG Key ID: 30D341DD34118D7D
3 changed files with 115 additions and 135 deletions

Binary file not shown.

View File

@ -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}

View File

@ -62,3 +62,8 @@
short = DEP, short = DEP,
long = data execution prevention long = data execution prevention
} }
\DeclareAcronym{vmt}{
short = VMT,
long = virtual method table
}