# Saturday, 19 November 2005

My first lesson was...

It is over an year from my first lesson as an assistant professor at the University of Trento, held while I was writing my thesis. The course was on Security and Privacy, and my lessons where on Software Attacks and how to prevent them. I do not claim to be a Security expert, I'm not, but my love for compilers, inner OS working and my willing to know "how it works inside" provided me with some knowledge to show the others what happens when a cracker gets control of your computer.
I always promised me to publish my lessons on the web. I also have some examples, but I don't think I'm going to publish them. They are all innocuos, since they only affect themselves, but maybe it's not so responsible to leave them "free" in the open air.. =). My first lesson was on general vulnerabilities, an introduction to the lexicon and to the first end simples type of software attack: the Buffer Overflow. If you want to read the whole Lesson you can find it here (in PowerPoint format).

If you, like me, are lazy, here is a little appetizing of what you will found, to see if it's worth your time. I hope so!
When you compile a C program, the instruction are translated into ASM code (and then to machine code, but here is almost a 1-1 mapping). As we saw some days ago, on an x86 machine most of the data (parameters, local space) is held on the stack. As an example, consider the following C code:

void f(int a, int b)
{
char buffer[20];
int i;
int j;
j = a;
i = a + b;
}

int main()
{
f(2, 3);
return 0;
}

When we compile it, it is translated to the following ASM instructions:

; 3    : {

   push  ebp
   mov   ebp, esp
   sub   esp, 28              
   
; 4    :    char buffer[20];
; 5    :    int i;
; 6    :    int j;   
; 7    :    j = a;
; 8    :    i = a + b;

   mov   eax, DWORD PTR [ebp + 8h] ; a
   mov   DWORD PTR [ebp - 8], eax ; j EBP - 8
   add   eax, DWORD PTR [ebp + 0Ch] ; b
   mov   DWORD PTR [ebp - 4], eax ; i EBP - 4
 
; 9    : }

   mov   esp, ebp
   pop   ebp
   ret   0

; 12   : {

   push  ebp
   mov   ebp, esp
   sub   esp, 0

; 13   :    f(2, 3);

   push  3
   push  2
   call  _f

; 14   :    return 0;

   xor   eax, eax

; 15   : }

   mov   esp, ebp
   pop   ebp
   ret   0

From the assembly code, you can see how parameters and locals are translated to stack space. The return address (the point from which the instruction is called, and to which we should return) is also saved on the stack. Can you see it? If we fill the buffer with over 20 character we will spill over, "invade" the space of the other locals, of the return address, and of the other parameters.

void func()
{
char buffer[20];
char* current = buffer;
int i;

for (i = 0; i < 256; ++i)
{
*current = 'A';
++current;
}
}

int main()
{
func();
return 0;
}

What will happen? A memory access error ("This program will be terminated" on Win32, "Segmentation fault" on Linux), surely. But, if you compile and execute the code, at which address the fault will happen? (Suggestion: the ASCII code for 'A', repeated four time, is a memory address in the 32-bit virtual memory space of your process).

Now with another example program we try to spill the buffer in a clever way: knowing that at memory address 0x00401090 there is an "interesting" piece of code, we can try to "return" to it, instead of returning to main.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//00401090
static char message[] = "AAAAAAAAAAAAAAAAAAAAAAAA\x90\x10\x40\x00";


void handleRequest()
{
char buffer[20];
strcpy(buffer, message);
printf("Request: %s\n", buffer);
}

void doNastyThings()
{
printf("He he!!\n");
}

int main()
{
while(1)
{
handleRequest();
}
return 0;
}

Compile it with VC++ 6.0 (if you have another compiler, obviously the address of the doNastyThings function will change: fix it). Surprised to see "He he!!" on the console? Have I tickled your brains? So, to see how it works.. Let's read my lesson!

BufferOverflow.ppt (162 KB)