Preventing bufferoverruns
- Canary on the stack
Put random value (canaries) on the stack after return
address. Check that the random value has not changed
before returning. Requires recompilation, small runtime overhead
paid for each function call. Has been worked around in some cases, for example, overwriting function pointers.
Anatomy of a Stack Smashing Attack and How GCC Prevents It - Address space layout randomization (ASLR)
Preventing exploitation of memory corruption vulnerabilities by preventing an attacker from reliably jumping to particular memory locations. ASLR randomly arranges the address space of key data areas of a process, for example
the base of the executable, the positions of the stack, heap and libraries.As far as our stack based bufferoverruns are concerned, start a process with
the top of stack (esp) in a ‘random’ location.
Used in RH9 and beyond (for example), this makes it
more difficult to determine where shellcode will reside on the stack.
Small initial startup cost, foils old exploits, can be done without
recompiling code. Unfortunately, this has been worked around. - Mark the stack non-executable
Do not allow the CPU to execute code on the stack.
Problems: Does not prevent heap overruns.
In C one can also pass function pointers (on the stack),
these would still be vulnerable. Some applications
need an executable stack. - Don’t use bad functions
strcpy(), strcat(), sprintf(). Note:
strncpy(), strncat() may leave buffer unterminated,
encourage off by one errors, so are not as safe as one might think. - Use safe versions of C libraries (libsafe)
Intercepts calls to ‘bad’ functions. Checks that there
is sufficient space in the current stack frame for the
call.
Problems: Won’t work for statically linked programs.
Only catches overflows in library code, for example:
while(*c!=’\0′){
*p++=*c++;
}
- Use safer languages
Java, C#, ML
Problems: Might not have a choice.
System might (probably will) rely on old libraries which are exploitable.
C functions that don’t know their inputs
function | description | safer alternative | description |
---|---|---|---|
gets | read from stdin until ‘\0’ or ‘\n’ and place in buffer | fgets | can specify maximum length of string to be placed in buffer |
strcpy | copy from one buffer to another (up to ‘\0’) | strncpy | specify max amount of data to be copied |
strcat(dest, src) | copy characters in src to the end of dest | strncat | only the first n characters of src are appended |
sprintf | format contents of one buffer and place in another buffer | snprintf | size of destination buffer is specified |
scanf | read formatted input from stdin, dangerous if used with an unbounded specifier like %s | scanf with bounded format specifier |
used with bounded size format specifiers is ok |