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.
Buffer overflows generally lead to crashes. Other attacks leading to
lack of availability are possible, including putting the program into an
infinite loop.
Integrity
Confidentiality
Availability
Access Control
Technical Impact: Execute unauthorized code or
commands; Bypass protection
mechanism
Buffer overflows often can be used to execute arbitrary code, which is
usually outside the scope of a program's implicit security
policy.
Integrity
Confidentiality
Availability
Access Control
Other
Technical Impact: Execute unauthorized code or
commands; Bypass protection
mechanism; 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)
Example
Language: C
#define BUFSIZE 256
int main(int argc, char **argv) {
char buf[BUFSIZE];
strcpy(buf, argv[1]);
}
The buffer size is fixed, but there is no guarantee the string in
argv[1] will not exceed this size and cause an overflow.
Example 2
This example takes an IP address from a user, verifies that it is
well formed and then looks up the hostname and copies it into a
buffer.
(Bad Code)
Example
Language: C
void host_lookup(char *user_supplied_addr){
struct hostent *hp;
in_addr_t *addr;
char hostname[64];
in_addr_t inet_addr(const char *cp);
/*routine that ensures user_supplied_addr is in the right
format for conversion */
validate_addr_form(user_supplied_addr);
addr = inet_addr(user_supplied_addr);
hp = gethostbyaddr( addr, sizeof(struct in_addr),
AF_INET);
strcpy(hostname, hp->h_name);
}
This function allocates a buffer of 64 bytes to store the hostname,
however there is no guarantee that the hostname will not be larger than
64 bytes. If an attacker specifies an address which resolves to a very
large hostname, then we may overwrite sensitive data or even relinquish
control flow to the attacker.
Note that this example also contains an unchecked return value (CWE-252) that can lead to a NULL pointer dereference (CWE-476).
Potential Mitigations
Phase: Build and Compilation
Strategy: Compilation or Build Hardening
Run or compile the software using features or extensions that
automatically provide a protection mechanism that mitigates or
eliminates buffer overflows.
For example, certain compilers and extensions provide automatic buffer
overflow detection mechanisms that are built into the compiled code.
Examples include the Microsoft Visual Studio /GS flag, Fedora/Red Hat
FORTIFY_SOURCE GCC flag, StackGuard, and ProPolice.
Effectiveness: Defense in Depth
This is not necessarily a complete solution, since these mechanisms
can only detect certain types of overflows. In addition, an attack could
still cause a denial of service, since the typical response is to exit
the application.
Phase: Architecture and Design
Use an abstraction library to abstract away risky APIs. Not a complete
solution.
Phase: 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.
Phase: Implementation
Implement and perform bounds checking on input.
Phase: Implementation
Do not use dangerous functions such as gets. Use safer, equivalent
functions which check for boundary errors.
Phase: 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)
A stack-based buffer overflow is a weakness where the code path includes a
buffer write operation such that:
1. stack allocation of a buffer
2. data is written to the buffer where
3. the expected size of the buffer is greater than the actual size of
the buffer where
expected size is equal to size of data added to position from
which writing operation starts
References
[REF-11] M. Howard and
D. LeBlanc. "Writing Secure Code". Chapter 5, "Stack Overruns" Page 129. 2nd Edition. Microsoft. 2002.
[REF-17] Michael Howard, David LeBlanc
and John Viega. "24 Deadly Sins of Software Security". "Sin 5: Buffer Overruns." Page 89. McGraw-Hill. 2010.
[REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 3, "Nonexecutable Stack", Page
76.. 1st Edition. Addison Wesley. 2006.
[REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 5, "Protection Mechanisms", Page
189.. 1st Edition. Addison Wesley. 2006.
More information is available — Please select a different filter.
Page Last Updated:
January 18, 2017
Use of the Common Weakness Enumeration and the associated references from this website are subject to the
Terms of Use. For more information, please email
[email protected].