|
|
|
Lecture 18 — buffer overflow
|
|
|
|
|
what is a buffer overflow?
|
|
|
|
|
void echo() { char buf[8]; gets(buf); puts(buf); }
|
|
|
|
|
gets does not do any bounds checking
|
|
|
|
|
any input longer than 7 characters will write past the end of buf
|
|
|
|
|
stack layout
|
|
|
|
|
stack frame
|
|
|
|
|
section of the stack set aside for each function call
|
|
|
|
|
pushed on the stack when function is called, popped off when function returns
|
|
|
|
|
contains:
|
|
|
|
|
return address
|
|
|
|
|
pointer to previous stack frame (i.e., the stack frame of the function that called this one)
|
|
|
|
|
local variables
|
|
|
|
|
arguments for next function call
|
|
|
|
|
int bar(char *arg, char *out) { strcpy(out, arg); return 0; }
void foo(char *argv[]) { char buf[256]; bar(argv[1], buf); }
int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "target1: argc != 2\n"); exit(1); } foo(argv); return 0; }
|
|
|
|
|
what does the stack look like after bar has been called?
|
|
|
|
|
buffer overflow attack
|
|
|
|
|
what do we need to have?
|
|
|
|
|
attack code
|
|
|
|
|
size of the buffer
|
|
|
|
|
location of the buffer
|
|
|
|
|
use gdb to verify stack layout
|
|
|
|
|
examine location of args, frames, ebp, eip, sp
|
|
|
|
|
sneak peek of assembly
|
|
|
|
|
run with too long argument to verify it overwrites return address
|
|
|
|
|
write exploit
|
|
|
|
|
use gdb to find location of the buffer
|
|
|
|
|
defenses against buffer overflow attacks
|
|
|
|
|
avoid vulnerabilities
|
|
|
|
|
use library functions that limit string lengths
|
|
|
|
|
fgets instead of gets
|
|
|
|
|
strncpy instead of strcpy
|
|
|
|
|
%ns instead of %s in scanf
|
|
|
|
|
system-level protections
|
|
|
|
|
random stack offsets
|
|
|
|
|
requires attacker to guess random offset correctly
|
|
|
|
|
In Linux, controlled by code written to /proc/sys/kernel/randomize_va_size (0, 1, or 2)
|
|
|
|
|
make stack non-executable
|
|
|
|
|
have compiler insert “stack canaries”
|
|
|
|
|
put a special value between buffer and return address
|
|
|
|
|
check for corruption before leaving function
|
|
|