here's everything vax has been saying, just so people can see what's going on with it.
I grow weary of people who ask 'lets use a buffer overflow in xxxxx' without understanding what a buffer overflow is or how to exploit it.
Simply put, a buffer overflow is a bug in software of firmware. These bugs are usually found in code that processes user input, network stacks, or file handlers. Black hats usually use them to inject custom instruction sequences into a secure system in order to crash the machine, or take control of it.
To understand a buffer overflow, lets talk about how data is stored in most modern computers. There are three types of data available to the programmer: stack, bss, and heap. Microcontrollers implement a fourth (rom) to store static strings like "Hello, World".
Stack or automatic variables are created when a function is entered, and "go away" when the function exits. The data stored there doesn't actually get erased, but may be overwritten at any time by other function calls. Most buffer overflows exploit this type of storage.
BSS or global data is uninitialized storage that is allocated when the program starts, and the data is always available. Most processors (with the exception of microcontrollers) put strings and constant data here as well.
Heap data is allocated and deallocated completely at the whim of the executing program. Since there is usually some variablilty in the order of allocation and release of heap data, it is difficult to execute a buffer overflow here.
For this discussion, I will focus on stack variables. Imagine a computer executes the following code snippet:
CODE
func();
{
int x,y;
x = 1;
y = 2;
load_font("Nifty.fnt");
x = y+1;
y = x+1;
}
load_font(char *name)
{
int length;
char font_buff[1024];
int num;
FILE *inf;
// Open the file
inf = fopen(name,"r");
if (inf == NULL)
throw_error("Font file doesn't exist\n");
// Get the length
fread( &length, 1, sizeof(int), inf );
if ( length > 1024 )
throw_error("Badly formatted font file\n");
// Load the fonts
num = fread( &font_buff[0], length, 1, inf );
if ( num != length )
throw_error("Badly formatted font file\n");
// Close file
fclose(inf);
}
Before executing the function call, the stack looks like this (I'm ignoring complications like the frame pointer, etc)
SP -> Empty
SP+1 -> 2 (y is stored here)
SP+2 -> 1 (x is stored here)
SP+3 -> return address to 'func' caller
SP+4 -> other stuff
Inside the load_font() function the stack looks like:
SP -> Empty
SP+1 -> inf
SP+2 -> num
SP+3 -> font_buff
SP+1026 -> length
SP+1027 -> return address to func
SP+1028 -> 2 (y is stored here)
SP+1029 -> 1 (x is stored here)
SP+1030 -> return address
SP+1031 -> other stuff
So, what happens if we load 1032 bytes instead of the 1024 the program was designed for?
Answer: font_buff is loaded completely, length and the return address to func are both overwritten. With the return address changed, when the program trys to return to func it will jump instead to an address of our choosing. If we are clever, and put a hand written piece of assembly language into font_buff, and change the return address to point to it, we can do anything we want.
So, how do you combat a buffer overflow exploit? (I believe the 360 uses most of these, but I could be wrong...)
0) Don't write bad code. Can you spot the bug in the code snippet above? It is similiar to one which compromised the original xbox.
1) Put the stack in memory with the no-execute flag set. This prevents changing the return address to point to the stack from executing code.
2) Randomize where programs get loaded. This prevents the hand tooled assembly language routine from calling a library function to launch an unsigned executable.
3) Sign everything. This prevents someone from changing system files. Note, if the code that checks the signature has a bug, signing may not help.
4) Put the signing key in ROM so it can't be changed.
5) Don't allow writing into memory marked with execute permission. Since memory sections can overlap, you also have to recognize when a data page (with write permission) maps into the same physical memory as a code page.
All for now...
VAX