WIS-SEC-BOF/work/01paper.tex

342 lines
14 KiB
TeX
Raw Normal View History

2019-10-21 15:40:47 +02:00
\documentclass[conference]{IEEEtran}
\IEEEoverridecommandlockouts{}
2019-12-11 20:21:10 +01:00
% The preceding line is only needed to identify funding in the first footnote.
% If that is unneeded, please comment it out.
2019-10-29 11:09:23 +01:00
\usepackage{csquotes}
\usepackage[style=ieee,backend=biber]{biblatex}
\addbibresource{./bibliography.bib}
2019-10-21 15:40:47 +02:00
\usepackage{amsmath,amssymb,amsfonts}
\usepackage{algorithmic}
\usepackage{booktabs}
\usepackage{graphicx}
\usepackage{textcomp}
\usepackage{xcolor}
2019-12-10 20:36:42 +01:00
\usepackage{caption}
\usepackage{subcaption}
2019-10-21 15:40:47 +02:00
2019-11-19 21:18:50 +01:00
% code listings
\usepackage{minted}
\usepackage{relsize}
% acronyms
\usepackage{acro}
\acsetup{list-long-format=\capitalisewords}
2019-10-21 15:40:47 +02:00
%additional packages
%\usepackage[ngerman]{babel}
\usepackage[utf8]{inputenc}
\usepackage{hyperref}
\usepackage{url}
%%fuer abkuerzungen begin
\usepackage[acronym,hyperfirst = false]{glossaries}
\glsdisablehyper{}
2019-12-11 20:21:10 +01:00
%\usepackage[acronym,acronymlists={main,
%abbreviationlist},shortcuts,toc,description,footnote]{glossaries}
2019-10-21 15:40:47 +02:00
\newglossary[clg]{abbreviationlist}{cyi}{cyg}{List of Abbreviations}
\newglossary[slg]{symbolslist}{syi}{syg}{Symbols}
\renewcommand{\firstacronymfont}[1]{\emph{#1}}
\renewcommand*{\glspostdescription}{} % Punkt am Ende jeder Beschreibung entfernen
\renewcommand*{\acrnameformat}[2]{#2 (\acronymfont{#1})} % Langform der Akronyme
\makeglossaries{}
\date{\today}
\input{glossary}
%%fuer abkuerzungen end
2019-11-19 21:18:50 +01:00
\include{acronyms}
2019-10-21 15:40:47 +02:00
\begin{document}
2019-10-22 11:04:52 +02:00
\title{Overview Over Attack Vectors and Countermeasures for Buffer Overflows}
2019-10-21 15:40:47 +02:00
2019-10-22 11:04:52 +02:00
\author{\IEEEauthorblockN{Valentin Brandl}
2019-10-21 15:40:47 +02:00
\IEEEauthorblockA{\textit{Faculity of Computer Science and Mathematics} \\
\textit{OTH Regensburg}\\
Regensburg, Germany \\
valentin.brandl@st.oth-regensburg.de\\
MatrNr. 3220018}
}
\maketitle
\begin{abstract}
TODO
\end{abstract}
\begin{IEEEkeywords}
Buffer Overflow, Software Security
\end{IEEEkeywords}
\section{Motivation}\label{ref:motivation}
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), the programm could read or write out of bounds of a buffer
2019-11-20 20:03:53 +01:00
(information leaks, \acp{bof}). Languages that are affected by this are e.g. C,
C++ and Fortran. These languages are still used in critical parts of the worlds
infrastructure, either because they allow to implement really performant
programms, because they power legacy systems or for portability reasons.
Scientists and software engineers have proposed lots of solutions to this
problem over the years and this paper aims to compare and give an overview about
those.
2019-10-21 15:40:47 +02:00
Reading out of bounds can result in an information leak and is less critical
2019-11-20 20:03:53 +01:00
than \acp{bof} in most cases, but there are exceptions, e.g.\ the Heartbleed bug
in OpenSSL which allowed dumping secret keys from memory. Out of bounds writes
are almost always critical and result in code execution vulnerabilities or at
least application crashes.
In 2018, 14\% (2368 out of 16556)~\cite{Cve2018} of all software vulnerabilities
2019-12-09 13:04:39 +01:00
that have a CVE assigned, were overflow related. This shows that, even if this
2019-11-20 20:03:53 +01:00
type of bug is very old and well known, it's still relevant today.
2019-10-21 15:40:47 +02:00
2019-11-19 21:18:50 +01:00
\section{Background}\label{ref:background}
2019-10-21 15:40:47 +02:00
2019-10-29 11:18:38 +01:00
% TODO: many references
2019-11-19 21:18:50 +01:00
\subsection{Technical Details}
2019-10-28 12:41:43 +01:00
2019-11-20 20:03:53 +01:00
Exploitation of \ac{bof} vulnerabilities almost always works by overriding the
return address in the current stack frame, 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. Other ways include overriding addresses in the \ac{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.
A simple vulnerable programm might look like this:
\begin{minted}{c}
int main(int argc, char **argv) {
char buf[50];
for (size_t i = 0; i < strlen(argv[1]); i++) {
buf[i] = argv[1][i];
}
return 0;
}
\end{minted}
2019-10-21 16:44:53 +02:00
2019-12-10 20:36:42 +01:00
A successful exploit would place the payload in the memory by supplying it as an
argument to the programm and eventually overwrite the return address by
providing an input $> 50$ and therefore writing out of bounds. When the
\mintinline{C}{return} instruction is executed, and jumps into the payload, the
attacker's code is executed. This works due to the way, how function calls on
CPUs work. The stack frame of the current function lies between the two pointers
\ac{bp} and \ac{sp} as shown in~\ref{fig:before}. When a function is called, the
value of the \ac{bp}, \ac{sp} and \ac{ip} is pushed to the stack
(Fig.~\ref{fig:call}) and the \ac{ip} is set to the address of the called
function. When the function returns, the old \ac{ip} is restored from the stack
and the execution continues from where the function was called. If an overflow
overwrites the old \ac{ip} (Fig.~\ref{fig:exploit}), the execution continues in
attacker controlled code.
\begin{figure}[h!]
\includegraphics[width=.3\textwidth]{./dot/before.pdf}
\caption{Stack layout before function call}\label{fig:before}
\end{figure}%
\begin{figure}[h!]
\includegraphics[width=.3\textwidth]{./dot/call.pdf}
\caption{Stack layout after function call}\label{fig:call}
\end{figure}%
\begin{figure}[h!]
\includegraphics[width=.3\textwidth]{./dot/exploit.pdf}
\caption{Stack layout after overflow}\label{fig:exploit}
\end{figure}
This is only one of several types and exploitation techniques but the general
idea stays the same: ovewrite the return address or some kind of function
2019-12-11 20:21:10 +01:00
pointer (e.g.\ in vtables or the \ac{plt}) and once that function is called, the
2019-12-10 20:36:42 +01:00
execution flow is hijacked and the attacker can execute arbitiary code.
2019-12-11 20:21:10 +01:00
The most trivial kinds of exploits is known as a \mintinline{ASM}{NOP} sled.
Here the attacker appends as many \mintinline{ASM}{NOP} instructions before any
shellcode (e.g.\ to invoke \mintinline{shell}{/bin/sh}) and points the
overwritten \ac{ip} somewhere inside the \mintinline{ASM}{NOP}s. The execution
\enquote{slides} through the \mintinline{ASM}{NOP}s until it reaches the
shellcode. Most of the migration techniques described in this paper protect
against this kind of exploit but there are different and more complex ways of
exploiting \acp{bof} that are not that easily migrated.
2019-11-19 21:18:50 +01:00
\subsection{Implications}
2019-10-28 12:41:43 +01:00
2019-11-19 21:18:50 +01:00
\section{Concept and Methods}\label{ref:concept}
2019-10-21 16:44:53 +02:00
2019-11-19 21:18:50 +01:00
\subsection{Methods}
2019-12-09 13:04:39 +01:00
This paper describes several techniques that have been proposed to fix the
2019-11-20 20:03:53 +01:00
problems introduced by \acp{bof}. The performance impact, effectiveness (e.g.\
did the technique actually prevent exploitation of \acp{bof}?) and how realistic
2019-12-09 13:04:39 +01:00
it is for developers to use the technique in real-world code (e.g.\ is
incremental introduction into an existing codebase possible). In the end, there
is a discussion about the current state.
2019-11-19 21:18:50 +01:00
\subsection{Runtime Bounds Checks}
2019-10-28 11:46:07 +01:00
2019-11-20 20:03:53 +01:00
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
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. Still almost any language
2019-12-11 20:21:10 +01:00
that comes with a runtime, uses runtime checking. For this technique to be
effective effective in general, writes to a raw pointer must be disallowed.
Otherwise the security checks can be circumvented.
2019-10-28 11:46:07 +01:00
2019-11-19 21:18:50 +01:00
\subsection{Prevent/Detect Overriding Return Address}
2019-10-28 11:46:07 +01:00
2019-11-20 20:03:53 +01:00
Since most traditional \ac{bof} 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. \citeauthor{Rad2001} 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 \mintinline{ASM}{RET}
instruction is actually executed~\cite{Rad2001}. While this is effective against
2019-11-19 21:18:50 +01:00
\ac{rop} based exploits, it does not protect against vtable overrides.
2019-10-28 11:46:07 +01:00
An older technique from 1998 proposes to put a canary word between the data of a
2019-11-20 20:03:53 +01:00
stack frame and the return address~\cite{Stackguard1998}. When returning, the
canary is checked, if it is still intact and if not, a \ac{bof} 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.
2019-10-28 11:46:07 +01:00
2019-11-19 21:18:50 +01:00
\subsection{Restricting Language Features to a Secure Subset}
\subsection{Static Analysis}
\subsection{Type System Solutions}
2019-10-28 11:46:07 +01:00
2019-10-29 11:09:23 +01:00
\citeauthor{Dep2007} propose an extension to the C type system that extends it
2019-11-19 21:18:50 +01:00
with dependent types. These types have an associated value, e.g.\ a pointer type
2019-10-29 11:09:23 +01:00
can have the buffer size associated to it. This prevents indexing into a buffer
2019-11-19 21:18:50 +01:00
with out-of-bounds values. This extension is a superset of C so any valid C code
2019-12-09 13:04:39 +01:00
can be compiled using the extension and the codebase is improved incrementally.
If the type extension is advanced enough, the additional information might form
the base for a formal verification.
2019-11-19 21:18:50 +01:00
\subsection{Address Space Layout Randomization}
2019-11-20 20:03:53 +01:00
\Ac{aslr} aims to prevent exploitatoin of \acp{bof} by placing code at random
locations in memory. That way, it is not trivial to set the return address to
point to the payload in memory. This is effective against generic exploits but
2019-12-09 13:04:39 +01:00
it is still posible to exploit \ac{bof} vulnerabilities in combination with
information leaks or other techniques like heap spraying. Also on 32 bit
systems, the address space is small enough to try a brute-force attempt until
the payload in memory is hit.
2019-10-28 11:46:07 +01:00
2019-11-19 21:18:50 +01:00
\subsection{w\^{}x Memory}
2019-10-22 11:04:52 +02:00
2019-11-19 21:18:50 +01:00
w\^{}x (also known as \ac{nx}) makes memory either writable or executable. That
way, an attacker cannot place arbitiary payloads in memory. There are still
techniques to exploit this by reusing existing executable code. The ret-to-libc
exploiting technique uses existing calls to the libc with attacker controlled
parameters, e.g.\ if the programm uses the \mintinline{shell}{system} command,
the attacker can plant \mintinline{shell}{/bin/sh} as parameter on the stack,
followed by the address of \mintinline{shell}{system} and get a shell on the
2019-12-11 20:21:10 +01:00
system. \ac{rop} (a superset of ret-to-libc exploits) uses so called \ac{rop}
gadgets, combinations of memory modifying instructions followed by the
\mintinline{ASM}{RET} instruction to build instruction chains, that execute the
desired shellcode. This is done by placing the desired return addresses in the
right order on the stack and reuses the existing code to circumvent the w\^{}x
protection. These combinations of memory modification followed by
\mintinline{ASM}{RET} instructions are called \ac{rop} chains and are turing
complete~\cite{Rop2007}, so in theory it is possible to implement any imaginable
payload, as long as the exploited program contains enough gadgets and the
overflowing buffer has enough space.
2019-10-22 11:04:52 +02:00
2019-11-19 21:18:50 +01:00
\section{Discussion}\label{ref:discussion}
2019-10-21 16:44:53 +02:00
2019-11-19 21:18:50 +01:00
\subsection{Ineffective or Inefficient}
2019-10-21 15:40:47 +02:00
2019-11-19 21:18:50 +01:00
\subsubsection{\ac{aslr}}
2019-10-21 15:40:47 +02:00
2019-12-10 20:36:42 +01:00
\Ac{aslr} has been really effective and wildly used in production. It is
2019-12-11 20:21:10 +01:00
included in most major operating systems~\cite{FBSDaslr}. Some even use kernel
\ac{aslr}~\cite{Linuxaslr}. Since this mechanism is active at runtime, it does
not require any changes in the code itself, the programm only has to be compiled
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}.
2019-10-21 15:40:47 +02:00
2019-11-19 21:18:50 +01:00
\subsubsection{w\^{}x}
2019-10-28 12:41:43 +01:00
2019-11-19 21:18:50 +01:00
With the rise of \ac{rop} techniques, w\^{}x protection has been shown to be
ineffective. It makes vulnerabilities harder to exploit but does not prevent
anything.
\subsubsection{Runtime Bounds Checks}
Checking for overflows at runtime is very effective but can have a huge
performance impact so it is not feasible in every case. It also comes with other
footguns. There might be integer overflows when calculating the bounts which
might introduce other problems.
Methods that have been shown to be ineffective (e.g.\ can be circumvented
easily) or inefficient (to much runtime overhead)\ldots
\subsection{State of the Art}
2019-10-21 15:40:47 +02:00
2019-10-28 12:41:43 +01:00
What techniques are currently used?
2019-11-19 21:18:50 +01:00
\subsection{Outlook}
2019-10-21 15:40:47 +02:00
2019-11-19 21:18:50 +01:00
\section{Conclusion}\label{ref:conclusion}
2019-10-21 15:40:47 +02:00
2019-11-20 20:03:53 +01:00
While there are many techniques, that protect against different types of
\acp{bof}, none of them is effctive in every situation. Maybe we've come to a
2019-10-28 11:46:07 +01:00
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.
2019-10-21 15:40:47 +02:00
2019-11-20 20:03:53 +01:00
\section{Sources (Dummy Section for Deadline)}
2019-10-21 15:40:47 +02:00
2019-10-22 11:04:52 +02:00
\begin{itemize}
2019-10-21 15:40:47 +02:00
2019-11-20 20:03:53 +01:00
\item RAD:\ A Compile-Time Solution to Buffer Overflow Attacks~\cite{Rad2001}
2019-11-19 21:18:50 +01:00
(might not protect against e.g.\ vtable overrides, \ac{plt} address changes,
2019-10-22 11:04:52 +02:00
\dots)
2019-10-21 16:44:53 +02:00
2019-11-20 20:03:53 +01:00
\item Dependent types for low-level programming~\cite{Dep2007}
2019-10-21 15:40:47 +02:00
2019-10-22 11:04:52 +02:00
\item StackGuard: Automatic Adaptive Detection and Prevention of
2019-11-20 20:03:53 +01:00
Buffer-Overflow Attachs~\cite{Stackguard1998} (ineffective in combination
2019-10-22 11:04:52 +02:00
with information leaks)
2019-10-21 15:40:47 +02:00
2019-11-20 20:03:53 +01:00
\item Type-Assisted Dynamic Buffer Overflow Detection~\cite{TypeAssisted2002}
2019-10-21 15:40:47 +02:00
2019-11-19 21:18:50 +01:00
\item On the Effectiveness of NX, SSP, RenewSSP, and \ac{aslr} against Stack
2019-11-20 20:03:53 +01:00
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}
2019-11-19 21:18:50 +01:00
2019-10-22 11:04:52 +02:00
\end{itemize}
2019-10-21 15:40:47 +02:00
2019-11-19 21:18:50 +01:00
\printbibliography{}
2019-10-29 11:09:23 +01:00
% \bibliographystyle{IEEEtran}
% \bibliography{bibliography}
2019-12-09 13:04:39 +01:00
% \printacronyms{}
2019-10-21 15:40:47 +02:00
\end{document}
% vim: set filetype=tex ts=2 sw=2 tw=80 et spell :