A stack-based buffer overflow condition is a condition where
the buffer being overwritten is allocated on the stack (i.e., is a local
variable or, rarely, a parameter to a function).
Alternate Terms
Stack Overflow:
"Stack Overflow" is often used to mean the same thing as stack-based
buffer overflow, however it is also used on occasion to mean stack
exhaustion, usually a result from an excessively recursive function
call. Due to the ambiguity of the term, use of stack overflow to
describe either circumstance is discouraged.
Time of Introduction
Architecture and Design
Implementation
Applicable Platforms
Languages
C
C++
Common Consequences
Scope
Effect
Availability
Buffer overflows generally lead to crashes. Other attacks leading to
lack of availability are possible, including putting the program into an
infinite loop.
Access Control
Buffer overflows often can be used to execute arbitrary code, which is
usually outside the scope of a program's implicit security
policy.
Other
When the consequence is arbitrary code execution, this can often be
used to subvert any other security service.
Likelihood of Exploit
Very High
Demonstrative Examples
Example 1
While buffer overflow examples can be rather complex, it is possible
to have very simple, yet still exploitable, stack-based buffer
overflows:
(Bad Code)
C
#define BUFSIZE 256
int main(int argc, char **argv) {
char buf[BUFSIZE];
strcpy(buf, argv[1]);
}
Potential Mitigations
Phase
Description
Requirements
Use a language or compiler that performs automatic bounds
checking.
Architecture and Design
Use an abstraction library to abstract away risky APIs. Not a complete
solution.
Build and Compilation
Compiler-based canary mechanisms such as StackGuard, ProPolice and the
Microsoft Visual Studio /GS flag. Unless this provides automatic bounds
checking, it is not a complete solution.
Implementation
Implement and perform bounds checking on input.
Implementation
Do not use dangerous functions such as gets. Use safer, equivalent
functions which check for boundary errors.
Operation
Use OS-level preventative functionality, such as ASLR. This is not a
complete solution.
Background Details
There are generally several security-critical data on an execution stack
that can lead to arbitrary code execution. The most prominent is the stored
return address, the memory address at which execution should continue once
the current function is finished executing. The attacker can overwrite this
value with some memory address to which the attacker also has write access,
into which he places arbitrary code to be run with the full privileges of
the vulnerable program. Alternately, the attacker can supply the address of
an important call, for instance the POSIX system() call, leaving arguments
to the call on the stack. This is often called a return into libc exploit,
since the attacker generally forces the program to jump at return time into
an interesting routine in the C standard library (libc). Other important
data commonly on the stack include the stack pointer and frame pointer, two
values that indicate offsets for computing memory addresses. Modifying those
values can often be leveraged into a "write-what-where" condition.
Other Notes
Stack-based buffer overflows can instantiate in return address overwrites,
stack pointer overwrites or frame pointer overwrites. They can also be
considered function pointer overwrites, array indexer overwrites or
write-what-where condition, etc.
Weakness Ordinalities
Ordinality
Description
Primary
(where the
weakness exists independent of other weaknesses)